The weakest link in security is the human element. This statement gets regularly confirmed, when we are setting up OAuth2 or Open ID Connect at a customer. This blog explains the security issue and how you can overcome it with some very little effort.
In many organizations, there is no automated procedure to perform the necessary Azure AD configurations. So typically, you end up in a conference call where you have to explain the required Azure AD setup to a global administrator, who performs the required steps. App registrations get created, roles are defined and scopes get configured. Then, it’s time for the magical moment: the creation of the client secret.
The client secret gets created through the Azure portal. You have to copy it at the time of creation, otherwise you cannot retrieve back later on. So, what happens mostly? The client id and secret are being transferred to the development team via Microsoft Teams chat, email or SMS. In many cases, these secrets are being copied multiple times on developer machines, in OneNote or Notepad or – if we are lucky – in a password manager. While this might be an acceptable approach for developer workloads, it is an extremely high security risk for acceptance and production. Even more within a cloud environment, where API endpoints are often exposed on public internet.
The first solution might be using managed identity. It’s always good to have a look if you can benefit from this password-less security feature, but this is only possible for machine-to-machine communication, where your client resides in Azure.
If managed identity is not an option, we need to securely distribute the client id an secret. Azure Key Vault is the optimal service to store these credentials. The following Azure CLI script automates this process:
#Set variables $appRegistrationClientId = "TODO" $keyVaultName = "TODO" $keyVaultResourceGroupName = "TODO" #Generate client secret $appRegistrationClientSecret= $(az ad sp credential reset --name $appRegistrationClientId --credential-description "clientsecret" --query password -o tsv) #Create Key Vault az keyvault create --name $keyVaultName --resource-group $keyVaultResourceGroupName #Create secret for client id az keyvault secret set --name "client-id" --value $appRegistrationClientId --vault-name $keyVaultName #Create secret for client secret az keyvault secret set --name "client-secret" --value $appRegistrationClientSecret --vault-name $keyVaultName
It automates the generation of the client secret:
It automatically stores the client id and secret into Key Vault:
The client id an secret are now stored in Key Vault! How can you use them? These are the options, in preferred order:
- Use Managed Identity to retrieve the client id + secret and cache them in memory
- Use Service Principal credentials (secret or certificate) to retrieve the client id + secret and cache them in memory
- Integrate with Key Vault during the release process and store the client id + secret in your local config store
One of the weakest links about OAuth2 security, is the way the client id and secret are communicated and handled by the involved parties. This little automation ensures that the client id and secret are stored in a secure and audited location. If we can avoid the human element in security, we should do it.
Remember: sharing is caring!