Can any program running in the VM or any user logged into the VM get a token using the Azure Managed Service Identity? - azure-managed-identity

When we store the Service principal certificate/appKey in the VM (to access the keyvault), we could limit access to that file to just the user account running the program. Other users or accounts wouldn't have access to the secrets in keyvault.
When we use Azure Managed Service Identity to access keyvault from an IaaS VM, my understanding is that any user logged into the VM or any program running on the machine can access the keyvault secrets - is this true?
And if it is, doesn't that decrease the security in case one of the user accounts is compromised?

According to the article access Azure Key Vault, it seems this is true. If MSI is enabled, just need to invoke web request in the VM without e.g. appKey.
And if it is, doesn't that decrease the security in case one of the user accounts is compromised?
It should be, but the prerequisites of the access to the secret in the keyvault is the VM service principal was added as a role in Access control (IAM) and Access policies.
If you want to increase the security, you may need to remove the VM service principal in the Access policies, then it will not be able to access the secret, if you want to the service principal does not have the access to the keyvault at all, remove its role in Access control (IAM).
For more details, you could refer to: Secure your key vault.
Update:
From the doc #Arturo mentioned, it is the fact.
Any code running on that VM, is able to call the managed identities for Azure resources endpoint and request tokens.

Related

Does Corda support user credentials for Accounts / Party?

Does Corda support user credentials for Accounts / Party? Here there is a common username, password for the node access through RPC. Is there a way to validate the user (Node user / Account) in Corda as well?
Application user (Node user / Account) <----> Application <----> RPC Client <----> Cordapp (Node)
the only way to connect an external client to a node is using the Corda RPC Client
the configuration of the user that can connect to the RPC Client (i.e. username, password, permissions) is in the node.conf (explained here)
you can create multiple users in the node.conf. Up to you to assign these users to a node administrator, or to external users, depending on your security policies. You can set different permissions for each of them, and also set which CorDapp flows they can access to.
If your CorDapp does use Accounts (i.e the account library), and you want them to "run flows" (though, consider that accounts in Corda do not run flows, but it's always the node that run flows on their behalf) from an external client (e.g. a Web app), you have the possibility to:
create a RPC user in the node.conf for each account
create only one user for the RPC client and manage the authentication and authorization of the external users at application level, not Corda level (e.g. JWT, external database, AWS Cognito, etc..). Once authorized, the user can access the RPC client from the Web app and
a mix of the 1. and 2.
I would not recommend to delegate the authentication and authorization of external users only at Corda level. I would keep the concept of "accounts" in Corda and "external users" separated.

How to allow end user of the application to be able to access AWS DynamoDB?

I'm building a Java application which needs to access the DynamoDB. The application is intended to be used by several end users (not all of them are trusted). From my understanding, in order to access the AWS service,the AWS credentials need to be loaded at runtime on end users' machine via several ways described at https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html
However I don't feel it'll be safe to directly hardcode the access key and token into the application code, as this can be easily exposed. Given my end users don't have too much technology background, I don't want to add too many "pre-setup" steps before they can use the application.What will be best/feasible practise to distribute the credential to them?
Thanks for all opinions.
You probably need to be looking at AWS Cognito
An Amazon Cognito user pool and identity pool used together
See the diagram for a common Amazon Cognito scenario. Here the goal is
to authenticate your user, and then grant your user access to another
AWS service.
In the first step your app user signs in through a user pool and
receives user pool tokens after a successful authentication.
Next, your app exchanges the user pool tokens for AWS credentials
through an identity pool.
Finally, your app user can then use those AWS credentials to access
other AWS services such as Amazon S3 or DynamoDB.

Access Key Vault for a Service Fabric application using Azure Active Directory

I have an application that runs in a Service Fabric(SF) cluster and I wan't to access Key Vault from it.
The cluster hosts a number of applications and I want to give access to a Key Vault for my application without giving access to the other applications. By default an application runs under the same user as the SF cluster, but each applicatiuon has it's own unique name, mine has the name fabric:/application1.
My question is, is it possible to create an Active Directory application account for fabric:/application1 and grant access to the key vault?
I know it is possible to use the RunAs options in the SF manifest, but that requires me storing an encrypted password in the manifest/source code and I want to try and avoid this if possible.
AFAIK,
The only way to have this flexibility is using ClientID & Secret or Service Principal certificates and each application manage their own credentials.
Service Principal Certificate is already integrated to AD, but does not require the application, the user or the Host to be part of the domain, the only requirement is setup an user on AD to grant the permissions on Keyvault.
There are other solutions using AD integration, like Managed identities for Azure resources(Former: Managed Service Identity) but I am not sure if you are able to restrict access per application like you described, because the MI add this as a service in the node, so technically other applicaitons would have access as well, worth a try to validate if you can restrict this.
If you want to try this approach, you can use with Microsoft.Azure.Services.AppAuthentication for implicit authentication of the services running in your cluster, where the nodes are setup with Managed Identities extension like described here.
Something link this:
When you use the Microsoft.Azure.Services.AppAuthentication, the Step 2 will be handled by the library and you won't have to add much changes to your key vault auth logic.
When you run your code on an Azure App Service or an Azure VM with a
managed identity enabled, the library automatically uses the managed
identity. No code changes are required.
The following docs describe other options you can use for KeyVault Authentication.
PS: I've done other KeyVault integrations using Client Secrets and Certificates and they are secure enough, With Certificates you can store it on the managed store or with the application, I would recommend MI only if is a requirement for your solution.

Storing Azure Vault Client ID and Client Secret

I am using .NET Core 2.0 and ASP.NET Core 2.0 for application development. The "test" application is a .NET Core Console application. The core code I am writing is a class library. Once proper testing. I choose to do this since I won't be putting this to use for awhile (it's replacing older ASPNET code).
Anyway, since I have to work with a LOT of API keys for various services I decided to use Microsoft Azure Key Vault for storing the keys. I have this all setup and understand how this works. The test application uses a test Azure account so it's not critical. And since this is replacing legacy code and it's in the infancy, I am the sole developer.
Basically, I'm running into this issue. There's not too much information on Azure Key Vault from what I can see. A lot of examples are storing the Client ID and Secret in a plain text json file (for example: https://www.humankode.com/asp-net-core/how-to-store-secrets-in-azure-key-vault-using-net-core). I really don't understand how this can be secure. If someone were to get those keys they could easily access stored information Azure, right?
The Microsoft MSDN has a powershell command that grants access (I lost the original link, this is closest I can find: https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/setting-up-and-configuring-an-azure-key-vault/) My development operating system is Windows 10 and my primary server operating system is Debian.
How would I approach this?
Yes, you are right, the plain text config file could be used only during development, not for production purpose. And in general, available options depend on where and how you host an App.
If you have an Azure Web App, you have at least next built-in options (from the documentation):
add the ClientId and ClientSecret values for the AppSettings in the Azure portal. By doing this, the actual values will not be in the web.config but protected via the Portal where you have separate access control capabilities. These values will be substituted for the values that you entered in your web.config. Make sure that the names are the same.
authenticate an Azure AD application is by using a Client ID and a Certificate instead of a Client ID and Client Secret. Following are the steps to use a Certificate in an Azure Web App:
Get or Create a Certificate
Associate the Certificate with an Azure AD application
Add code to your Web App to use the Certificate
Add a Certificate to your Web App
You may also find an approach that uses env variables to store credentials. This may be OK only if you can guarantee that it's not possible to do a snapshot of env variable on prod machine. Look into Environment Variables Considered Harmful for Your Secrets for more details.
And the last one thing: there is also a technic that based on the idea, that you need to store/pass only a ClientSecret value while ClientId should be constructed based on machine/container details where the App is hosted (e.g. docker container id). I have found an example for Hashicorp Vault and an App hosted on AWS, but the general idea is the same: Secret management with Vault
In addition to the first answer, with the context of running applications on Azure VM, instead of using client_secret to authenticate, you can use client certificate authentication as explained in this documentation: Authenticate with a Certificate instead of a Client Secret.
In the picture above:
Application is authenticating to AAD by proving that it has the private key of the certificate (which is basically stored in CNG if you are using Windows).
Application get back the access_token and then use it to access the Key Vault.
The developer does not need to know the private key value of the certificate in order for their app to be successfully authenticated. Instead, they only need to know the location of the imported pfx (a container for private key and its certificate) in the Certificate Store.
At least on Windows, you as secret administrator can convert the private key and the certificate into pfx format which is password protected, and then deploy it into the Windows Certificate store. This way no one could know the private key unless they know the password of the pfx file.
The other approach specifics for Azure Compute, is to use Azure Managed Service Identity. Using Azure MSI, Azure will automatically assign your resources such as VM with an identity / Service Principal, and you can fire requests at a specific endpoint that are only accessible by your resource to get the access_token. But be wary that Azure MSI are still under public preview, so please review the known issues before using it.
The picture above explain how Azure Resource Manager assign a Service Principal identity to your VM.
When you enable MSI in a VM, Azure will create a service principal in your AAD.
Azure will then deploy a new MSI VM extension to your VM. This provides an endpoint at http://localhost:50432/oauth2/token to be used to get the access_token for the service principal.
You can then use the access_token to access the resources such as Key Vault which authorize the service principal access.

Problem setting SUBSCRIBE QUERY NOTIFICATIONS

I'm currently implementing a cache mechanisem for our site.
I want to use the SQL Cache dependancy feature.
I am running the following command in management studio and it's not working.
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO "my_server_name\ASPNET"
The error I'm getting is:
Cannot find the user 'my_server_name\ASPNET', because it does not exist or you do not have permission.
I tried signing in with the admin of the specific database I'm setting the notification for, sa, and windows authentication with the machine administrator.
Also tried running management studio as administrator and still not joy.
Can someone please point me in the right direction.
Thank you!
First, it appears you are attempting to grant permissions to the account under which the site is running. In IIS 6 and IIS7 these are control by the account set on the Application Pool. That account used to be ASPNET but no longer by default. Instead, the default (starting with .NET 2.0 I believe) is NETWORK SERVICE. However, if you are using IIS 7, that has changed yet again. By default in IIS7 it uses something called the "ApplicationPoolIdentity" which is its own special credential created for each site. If SQL Server is on a different machine than the web server, you will run into another problem which is the credentials are all local to the machine.
My recommendation would be to do the following depending on your setup:
Both servers are on a domain and you want to use trusted connections:
Create a domain account and drop it into Domain Users.
On the web server, drop this account into the IIS_IUSRS group.
Go into the Application Pool for the site and change the account under which the site is running to this domain account. You will also want to ensure that this account has the proper NTFS permissions to the site files. If this site only writes to the database, you can given the account read-only access the folder(s) with the site files.
Ensure the connection string used by the site is formed to request a trusted connection. (See www.connectionstrings.com for the syntax)
On the database server execute your grant to this account:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO "domain name\MyIISAccount"
There may also be other Kerberos issues related to the fact that both servers on the domain and that might require creating a SPN (Service Principal Name).
Neither server is on a domain (i.e., both are member servers) and you want to use trusted connections:
Create a local account on both the web server and the database server with the same username and password. It is critical that they both have the same username and password. This technique involves using NTLM "pass-through" authentication which matches the hash created by the username and password to determine if the user is authenticated between the two desparate servers. On Windows 2008 R2, you may have to jump through a few local policy hoops to ensure that NTLM is enabled between the two servers.
Do steps #2 to #4 above with this account.
On the SQL Server, ensure that this local account has a Login and that this login maps to a User in the database. Then you would execute something like:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO 'SQLServerMachineName\AccountUsedBySite'
You want to use SQL accounts instead of a trusted connection:
In this scenario, the connection string used by the site to connect to the database will include a username and password which map to a Login on the SQL Server database which maps to a User in the database (typically put in the db_owner role to make it dbo). This
Assuming the credentials are correct, you need only execute your grant against this user:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO 'SQLUserAccountUsedBySite'
Both IIS and SQL Server are on the same machine and you want to use trusted connections
Create a local user account and drop it into the Users group.
Drop this account into the local IIS_IUSRS group.
Go into the Application Pool for the site and change the account under which the site is running to this local account. You will also want to ensure that this account has the proper NTFS permissions to the site files. If this site only writes to the database, you can given the account read-only access the folder(s) with the site files.
Ensure the connection string used by the site is formed to request a trusted connection. (See www.connectionstrings.com for the syntax)
In SQL Server, create a login for this account then create a user in the appropriate database for this account dropping it into the appropriate roles.
Now execute your grant to this account:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO 'SQLServerMachineName\MyIISAccount'
Try this:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO [my_server_name\ASPNET]

Resources