This guide is going to break down how to create a secure password string in a logic app flow and upload this secret into a key vault using REST API.
I had previously explored executing java code in the Inline Code connector, which utilises an integration account to generate a password string. However, on further research articles such as this identify it is not secure. I needed to find a way to produce a cryptographically secure password string for use.
This has led me to the following solution, which I hope others will find useful.
Azure Automation Account & Python Script
- Create an Azure Automation Account
- Create an automation runbook using the Python with runtime version 3.8 (important we use this version)
3. Edit your runbook and paste in the Python script that will generate the password
#!/usr/bin/env python3
import secrets
import string
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(20)) # for a 20-character password
print(password)
4. Save & Publish the runbook to complete
Logic App
Within your logic app, create a connector from Azure Automation for ‘Create job’.
Specify the subscription, resource group, automation account & python runbook.
Check the wait for job parameter as we need the flow to pause while the runbook executes.
Create the ‘Get job output’ connector and specify the dynamic content for Job ID so we can grab the output of the runbook script.
Now if you were to manually trigger the logic app you can see the job output shows the password string that has been generated from the python runbook.
Uploading to Azure Key Vault
To expand further on this, you can publish the secret into a key vault using the REST API.
Managed Identity & Key Vault Access
- In your Logic App go to settings > Identity > Turn on System assigned managed identity
- Copy the managed identity principal ID that is generated for the identity
- Locate the key vault resource and grant the managed identity access (secret permissions) as per Microsoft docs under access policies on the key vault
Logic App & API Request
Create a HTTP request connector in the logic app and select PUT as our method of call.
Amend the {vaultBaseUrl} to your Key Vault URL which can be found on the Key Vault overview page.
The secret name can be anything you want, but it is probably best to specify a dynamic value so it will be different each run rather than updating the same secret.
URI:
{vaultBaseUrl}/secrets/{secret-name}?api-version=7.3
Body:
{
"value": "@{body('Get_job_output')}"
}
From the drop down ‘Add new parameter’ select Authentication and specify system-assigned managed identity with an audience URL:
https://vault.azure.net
Running the logic app to test should show it now creates a secure 20 character password from our runbook and then uses the REST API to create a secret with this value.
Closing thoughts
If you are running this within an existing process you may find it better to add steps to ask product owners what they want the key vault secret name to be, so you can use that as a dynamic value in the API request for each run.
Alternatively, create a random string for each run so it’s not updating the same secret with an updated password.
How do we know this is a cryptographically secure password generation method?
I’m happy with this solution as a secure password generator, as the official Python docs secrets — Generate secure random numbers for managing secrets — Python 3.11.0 documentation say this method will create “cryptographically strong random numbers suitable for managing data such as passwords”.
This is a new feature in Python versions 3.6 and newer which is why we have to use 3.8 (preview) in the runbook runtime version.
This ensures I know the passwords I’m generating in business flows are now meeting adequate security requirements for use cases.
What do you guys think, do you use a different approach? Let me know!
Thanks.
Troubleshooting
{
“error”: {
“code”: “Unauthorized”,
“message”: “AKV10022: Invalid audience. Expected https://vault.azure.net, found: https://management.azure.com/.”
}
}
You need to specify https://vault.azure.net in the audience field on the authentication of the HTTP connector.
Managed identities can sometimes take some time to propagate so allow some time before checking key vault access is successful in the logic.
References
secrets — Generate secure random numbers for managing secrets — Python 3.11.0 documentation
Set Secret – Set Secret – REST API (Azure Key Vault) | Microsoft Learn
You could completely cutout the logic App and add the password to the azure key vault using Powershell.
code
Set-AzKeyVaultSecret -VaultName SomeVault -Name somesecret -SecretValue (‘Password’ | ConvertTo-SecureString -AsPlainText -Force)
Hi Paul,
Thanks for the comment!
For it to stay automated you would probably want the logic app (or some sort of Function to call on) to tie it all together as one unit. Or unless you want to do the PS part manually outside the work flow, for sure.
I like the flexibility of the connectors in the logic app – tons of possibilities!
Dan