I'm using a "user managed identity" with the "AcrPull" role to allow my app services to pull images from my Azure container registry. I currently have the ID of this user managed identity defined in my Terraform config in plain text but I'm wondering if it's considered sensitive and I should have it as a secret instead. I know the service principal ID is not necessarily sensitive but the managed identity has no secret to go with it so it seems much more powerful on its own...
I currently have the ID of this user managed identity defined in my Terraform config in plain text but I'm wondering if it's considered sensitive and I should have it as a secret instead.
No it is not. Managed Identities are specifically designed to take away the burden to have any secret at all. The identities can only be used to enable Azure resources to communicate with services that support Azure AD authentication. So, if someone somehow does know the principal ID it can only use to grant or restrict access between azure resources. It cannot be used to gain access to the resource by the person himself.
Related
I am looking at the documentation of service principals , and come across these phrases
It's important to remove old service principals for the same reason that you delete old user accounts: attackers might gain access to their keys. It's best not to have credentials that aren't actively used.
You might wonder why you need to create this whole new type of object
just to authenticate a pipeline, when you have user accounts that work
perfectly well. User accounts aren't designed for unattended use. The
authentication process for a user account often checks that a human is
the entity that's trying to sign in. Increasingly, organizations use
additional security checks during authentication. These checks include
MFA, CAPTCHA checks, and inspecting the device and network that the
user is using so that they can verify the legitimacy of a request to
sign in.
It's also a bad idea to save your username and password anywhere, because someone else might get access to them and then use them to impersonate you.
In "both" theories, it seems it is not a good idea to keep / share service principals ( aka passwords ). Is it only reason that passwords are not designed for unattended use we should use service principals which offers secure measures on a case to case basis ?
As per the Official Microsoft Documentation,
When you have applications, hosted services, or automated tools that needs to access or modify resources, you can create an identity for the app. This identity is known as a service principal. Access to resources is restricted by the roles assigned to the service principal, giving you control over which resources can be accessed and at which level.
The user accounts and passwords are not designed for unattended use. Service princpals can be used to give the access to the resources based on the Role-based access control(RBAC).
What service principal object exactly do is it sets the information about a particular app and its resources access.
If you want to avoid the need to manage the credentials you can use Managed Identity.
Reference:
https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals#service-principal-object
People say not to store API Keys and passwords config files and instead to use a Secrets vault. eg. AWS or Azure.
But to access these you need a clientId and clientSecret. These need to be stored somewhere on the app. eg app.config. So I really don't understand what problem this solves if the hacker can use the clientId and clientSecret in the app the get the passwords or api keys anyway?
it seems even worse than the original problem storing one api key, since if they get access to the secrets manager they will have ALL THE KEYS and ALL the passwords.
AWS offers few different services to store your secrets. Let's say if you have a database password in an application configuration file, you can use either AWS Secret manager or AWS Parameter store to store them as secret.
To retrieve these values securely, you do not have to store another secret stored in your application. You can use a mechanism called role-based access in AWS.
If you running your application on an ec2 instance, you can configure an AWS role/profile and assign it to the ec2 instance which is linking the secret manager and the ec2 machine securely and your application has connectivity to decrypt the secret and use it inside the application.
If you are using Azure, the answer is to use Managed Identities.
The way it works is that you assign an identity to the resources (VMs, WebApps etc.) that need access to Key Vault. That way the resource becomes like a user in your Azure AD (much like a Service Principal or any other user). Then you can make use of Key Vault Access Policies to assign appropriate access to keys and secrets in your Key Vault to these Managed Identities. Doing this would not require you to specify a Client Id/Client Secret to access the Key Vault.
While the Managed Identity is something you assign to a resource, it could become cumbersome if you have many resources. That's where User Assigned Managed Identity comes into picture. A User Assigned Managed Identity is a resource in your Azure Subscription. The process is very much similar: you create such identity and then assign appropriate access to this identity on your Key Vault resources.
Now wherever you need to access Key Vault in your applications, you will specify the id of this identity. The application using appropriate SDK will get an access token on behalf of this identity and connect to Key Vault using that access token.
You can learn more about these identities here: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview.
But to access these you need a clientId and clientSecret. These need to be stored somewhere on the app. eg app.config
You can use runtime permissions to access the secrets and parameters. In Azure it is called Managed Identities, in AWS there are service roles. I am more familiar with AWS, so I will use its terminology, but every larger cloud provider has similar approach with different names.
Basically you can assign the compute resource where your code runs (EC2/VM server, Lambda function, ECS container,...) a role - you can consider it as set of permissions. Using AWS API you can access the secrets or parameters from the code without storing any client credentials.
if they get access to the secrets manager they will have ALL THE KEYS and ALL the passwords.
That's why we all need to use principle of the least privileges, the defined runtime identity should have only permissions it really needs.
I have a web API hosted on Windows server via IIS. I'm using Azure Key Vault to hide secrets. In order to give the application access to the vault, I am using a certificate installed on the server, which is also registered with the application in Azure.
The certs thumbprint, the tenant ID, and the application ID are all exposed in the configuration file of the web API. The apps registration is granted access via policy in the key vault.
The issue is that the integration assistant in Azure is alerting me that I should not have a certificate set up inside the registration, but with no explanation as to why (the documentation is greyed out for alert).
Can this alert be safely ignored? Or is there a better way to grant my application vault access?
Edit - snip of integration assistant:
Can this alert be safely ignored?
In your particular scenario, I would say yes. You can safely ignore this message.
Essentially you need a user to access the key vault. Considering your application is running locally, you would use the Service Principal (created as part of the app registration) as a user to access the key vault.
Or is there a better way to grant my application vault access?
In your particular scenario (when your application is running locally), AFAIK no.
If your application were running in Azure, you could have used Managed Identity. It could be either System-assigned Managed Identity or User-assigned Managed Identity. With managed identity, you need not require a secret/certificate based authentication.
I am not sure if your API is protected by Azure AD (i.e. a user must be authenticated/authorized before using the API), but if it does then one alternative would be to grant users of your API access to Key Vault. Requests to Key Vault will then be sent in context of that user. This however will increase the management complexity considerably as you have to manage access control for all your API users.
I'm trying to use Azure RBAC to secure access to storage blobs, and to use Azure Identity to access those blobs from Apache Spark. I see that recent versions of Hadoop-Azure support abfs, and it supports a few token providers: https://hadoop.apache.org/docs/current/hadoop-azure/abfs.html#Azure_Managed_Identity . For production usage, I can use a service principal with an AD app and the associated client id, secret, and endpoint. Or I can even use Managed Identity.
When developing locally, it would be good to be able to do the same with something like DeviceCodeCredential or InteractiveBrowserCredential, i.e. something that will make the user log in to Azure using a browser, and use the credentials returned to get the access token as pass it to Spark. The reason I'd like this is to have users use their own credentials when accessing data, and not have storage keys / SAS tokens / etc flying about.
Is something like this possible? I could implement a Custom Token Provider that wraps an Azure Identity instance, but was wondering if there were a less nuclear approach.
If you want to use the user credential to auth, the closest way in the supported auth ways is the OAuth 2.0: Username and Password, but essentially it uses the Azure AD ROPC flow to auth, it has some limits, e.g. it will not work with the user account which is MFA-enabled.
Actually, for local development, the way I most want to recommend is to use a service principal to auth i.e. OAuth 2.0 Client Credentials, because the MSI(managed identity) is essentially a service principal managed by azure, if you use MSI for production, the transition of the environment will be smoother, the permissions stuff in azure will be some differences between the user account and service principal in some scenarios(maybe not in this case). Of course, Custom Token Provider is also a feasible way, they all depend on yourself.
In my application I have to store very sensitive data of its users, such as various password to other 3rd part services (user fill a form where he provides us login and password to 3rd part service)
The goal of the application is to setup other complex system using powershell scripts generated from over 100 inputs. There is a requirement to save user work as draft, and that is why I need to encrypt sensitive fields somehow.
I read a lot about Azure Key Vault and whenever I read about secrets it seems they are described to hold app settings rather then users secrets, so i am not sure if this is right to place those data.
Is Azure Key Vault secrets suitable for that job?
Moreover i am able to peek those value in azure portal as in plain text, and I want to avoid that. I suppose that I could encrypt them first and store already encrypted values, but this may be over engineering.
It's not clear what you are describing as user secrets. If it's user credentials, then you need to federate login to an Identity Provider like Azure AD or Azure AD B2C. Key Vault is NOT an identity provider, but a secret store. If it's application secrets (think connection strings) then you should look at Key Vault (with Managed Service Identity).
Conversely, Application Settings (in App Service) are exposed in the Portal but are encrypted at rest. So if you're careful about who can access what within your subscription namespace, you should be just fine.