Anyone has suggestions on how to implement automated key rotation for service account credentials used in the cloud function, AppEngine, GKE.
GCP has added this as one of the recommended security policies for cloud-native services. We can find APIs/client libraries to generate a new private key for the existing service account. But we don't really get how to update the newly generated key on the application deployed in AppEngine, cloud function during runtime.
When you are on Google Cloud components, you don't have to use service account key files. It's a bad practice (even if presented as "standard" in too many tutorials, even Google Cloud tutorials!).
A service account key file is a nightmare to manage. It's a file. You can copy it, you can send it by email, you can even commit it in source repository (maybe public repo!!). In addition, you need to keep it secure and to rotate it regularly...
The best way to simplify this, is to not use them and to rely on Google Cloud component identity. Of course, for all external component, like a CI/CD, an on prem app (or on other cloud provider), the service account key file is the best way to be authenticated on Google Cloud
For Cloud Functions, you can use Cloud Functions Identity
For GKE, you can use Workload Identity
For App Engine, you can rely on the App Engine default service account
For you local development, perform a gcloud auth application-default login to create a default credential with your own user account
In each case, you can recover the default credential in your code. (here an example of a simple credential, without client library, only Google OAuth2 lib)
Note: For some operation, App Engine default service account isn't usable (generate an identity token based on metadata servers or changing the scope of the access_token). For this, I recommend you to impersonate service accounts instead of using service account key file
Related
I am hosting my Azure Functions as containers in my AKS cluster. Some of my functions have HTTP Triggers, and I don't want them exposed publicly (although security is not a huge concern so I also don't want to roll my own token authentication in there). These functions have never been deployed to Azure App Services, so there is no "Function App" and no "Function Name" that I can use to get a token (other than the Function Name that I put in the attribute on the methods in my code).
How can you access authorization keys for Azure Functions that are hosted in AKS?
You should be able to do this by setting AzureWebJobsSecretStorageType=kubernetes and reference your custom key via secret AzureWebJobsKubernetesSecretName=my-key-secret. This was introduced by this PR which documents that quite well: https://github.com/Azure/azure-functions-host/pull/4462
Let me give some details of my setup
I am building an asp.net core API app being hosted on Azure. I store my secret keys and stuff in azure keyvault. However, I have some AzureAddClientId and secret which is now stored in appsettings.json( to access key vault ). I have also committed appsettings.json to my git repo. However I know that is insecure. I use Azure DevOps for releases. So I'm thinking of doing the following. Please let me know your thoughts on this.
add appsettings.json to git ignore and share the file among developers.
add AzureAddClientId and AzureAADClientSecret to azure DevOps build pipeline as variables. ( Will devops automatically take the variables just as if they were in appsettings.json? )
Please have a look at using Managed Identities.
A common challenge when building cloud applications is how to manage the credentials in your code for authenticating to cloud services. Keeping the credentials secure is an important task. Ideally, the credentials never appear on developer workstations and aren't checked into source control. Azure Key Vault provides a way to securely store credentials, secrets, and other keys, but your code has to authenticate to Key Vault to retrieve them.
The managed identities for Azure resources feature in Azure Active Directory (Azure AD) solves this problem. The feature provides Azure services with an automatically managed identity in Azure AD. You can use the identity to authenticate to any service that supports Azure AD authentication, including Key Vault, without any credentials in your code.
I just wrote my first app with Azure. Just a small function app calling the IoT service and suddenly it hit me - I didn't have to create any IAM role or anything. The app just worked. I tried to look up the IAM service on Azure, but found nothing. This would never fly with AWS or Google Cloud. Does Azure have any IAM-like management anywhere? If my app has a bug that allows remote server-side code execution, does it mean that the attacker will basically gain access over my entire Azure account?
Azure does have role based access control and managed service identity (identity you assign to azure services, not all of the services have that yet). If you are using connection strings (usual pattern) nothing would happen if your app gets compromised. Attacker would be able to talk to your IoT Hub (or whatever you were using).
If you are using managed service identity then the attacker could, in theory, act on behalf of that identity. So if you grant all permission to that identity - then yes. Attacker would be able to do anything.
If your application talk to Azure REST Api directly to create\modify resources and gets compromised - attacker would, in theory, have the same rights as the application.
Having said that, I dont think Azure is any way less secure then AWS or GCP. Unless you grant the app all the permissions in the world - it has none to actually manage Azure.
Team,
I have recently migrated my azure classic portal resources to CSP subscription. I have successfully converted my azure cloud service to azure app website in the CSP subscription. But there is one thing i am not able connect. Its the third party API When we had the cloud service we had a .pfx uploaded to azure and in the code we use to create a uri which consists of the certifcate key + certificate secret key.
The certificate key is got directly from web.config. But the certificate secret key is got from EncryptedSettings.Appsettings("SecretKeyName").
This is basically got from the encrypted app setting done earlier by
https://eren.ws/2014/02/04/encrypting-the-web-config-file-of-an-azure-cloud-service/
But i am not sure what way should we implement on Azure website.
I have tried implementing the same but unfortunately it seems the secret key retrieval technique for cloud service is not the same as in the azure web app service.
When i debug the azure web site i can see that it gives the error as.
Failed to decrypt using provider ‘CustomProvider’. Error message from the provider: Value cannot be null.
Parameter name: keyObject
Can anyone please guide me ?
Rather than storing secrets in your config, you may wish instead to store them Azure KeyVault (which also gives you secret management capabilities etc) and then load the secrets at runtime.
KeyVault documentation:
https://learn.microsoft.com/en-us/azure/key-vault/
Specifically how to use keyvault with azure websites:
https://learn.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application
And these days, don't bother with manual authentication to use keyvault, instead use "Managed Service Identity", here's a tutorial:
https://azure.microsoft.com/en-gb/resources/samples/app-service-msi-keyvault-dotnet/
Interestingly the second tutorial does mention specifically using certificates for the purposes of authentication (against keyvault), you may wish to use this technique for yourself as a simplified way to get direct access to your certificate.
Does the Key Vault offer any benefit (security or otherwise) now that an app service can use Managed Identity to authenticate with other Azure resources? (E.g. azure storage and sql)
Is there any reason to use Managed Identity to access Key Vault and get a key for Storage, for example, now that an app service can directly use Managed Identity to talk to Storage?
You should always use Managed Service Identity where available, however they are not ubiquitous across all Azure. The list of supported services is maintained here. Keep in mind that the calling service needs to support authenticating with it's Managed Service Identity and the called service needs to be able to authenticate and authorise using Azure Active Directory.
When you have a service that does not directly support AD authentication (e.g. CosmosDB), then you still need to store and manage keys and KeyVault is still the right place to do this. This also applies to some 3rd party services like Salesforce, AWS, GCP, etc where "federation" may not be in place. You may also have additional sensitive config that you do not want to store in plain text.
Keep in mind that function appsettings can now directly reference KeyVault, saving the overhead of writing code and config to manage this yourself. See this link.
I would also say, that usage of managed identity should be preferred whenever possible. The major benefit I see is getting rid of credentials you have to manage. You outsource the authentication challenge to Microsoft here, and I would say it works very well.
One less credentials you need to protect, refresh, revoke etc.
I also believe that this goes well in the spirit of Infrastructure as a code, where you define you concern yourself with authorisation and leave secure authentication on the provider.