Securely distributing client secrets within the organization

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.

The problem

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 solution

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:

  1. Use Managed Identity to retrieve the client id + secret and cache them in memory
  2. Use Service Principal credentials (secret or certificate) to retrieve the client id + secret and cache them in memory
  3. Integrate with Key Vault during the release process and store the client id + secret in your local config store

Conclusion

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!
Toon

About me

Hi! I’m Toon Vanhoutte, a hands-on Azure architect – based in Belgium – with a big passion for teaching and helping people out. I’m happy to assist you during your Azure journey with high-quality advisory and I would love to teach you Azure’s possibilities via my tailored training courses.

Subscribe to the blog