Power Automate: Store your API Access tokens in Azure Key Vaults and automatically renew them!


Examining the picture, it illustrates a common habit in a typical Power Automate solutions. Meaning the credential details for API requests are visible in plain text – and we can just open the actions, copy and use the credentials elsewhere. For me, this is great (nothing beats customers that are giving me easy access to stuff) and I can instantly start working with their APIs in my projects without a fuzz! ๐Ÿ‘Œ

However, leaving these credentials out in the open is a bad practice, and especially for admins of any company that wants to take their security seriously. Additionally, when considering this architecture, it’s important to note that if a Power Automate flow includes the authentication calls, and is required to run every 5 minutes 24/7, it results in 288 wasted actions for just one flow running (as in getting the token, then parsing it). This is based on the “Actions per 24 hours” limit, as outlined in the Microsoft Learn article: Limits and configuration – Power Automate | Microsoft Learn). โ˜น๏ธ

A best practice for handling credentials is to store them securely in a password database, as a general rule. An even better option is to compliment Power Automate by utilize the Azure Key Vaults service, if the customer has an Azure tenant available.๐Ÿ”‘

In today’s blog post, we will not only conceal our API client ID and client secret information, but also enable automatic updating and renewing of the OAuth Token’s lifecycle with Power Automate. This removes the management and maintenance overhead of a team’s API credentials being used by developer teams! The flow is inspired by the same approach where some official Postman Collections has its own token renewal features.


The problems we are solving in Power Automate:

  • Learn how to create a scheduled Power Automate flow and update a Key Vault secret, such as an OAuth token based on its expiry date.
  • Learn how to create and store your credentials in Azure Key Vaults to safeguard your client ids and client secrets.
  • Learn how to create and utilize an API application with token through Azure AD App registration, and restrict its access to Azure Key Vaults when using “Get secret” actions or HTTP calls to update a Key Vault secret through Power Automate.

Prerequisites:



Getting Started: An Introduction to create Key Vaults for Beginners

Lets start with creating an Azure key vault, with two key vaults secrets. Make your way and login to the Azure portal (Microsoft Azure) and follow below:

Search for “Key vaults” and navigate to the service

Click “Create” once in the menu to create a new Key Vault. If you already have an existing Vault, you can skip the instructions on creating a new one.

Select your existing Subscription, Resource Group you want it to “live in” and give the new key vault a name that’s not been taken (e.g: *YourName*-Key-Vault) and select your Region. When you’re done, click on “Review + create”.

Click on “Create” on the next page to start the creation.

The creation will take a few seconds and when it’s complete, click on the “Go to resource” button.

Create/Generate two secrets where each of them has one value… One secret has the value of client-id and the other value of client-credentials.

Great! Now we’ve setup the Azure Key Vault, next we’re going to use the Azure App registration to create an application that gives us the proper access to interact with this new Azure Key Vaults through API calls. This is because the default Power Automate – Key Vault connector is limited to what we are going to do!


Creating the Key Vaults API application for our HTTP update requests in Power Automate

This API application is designed to allow for updating our Key Vault secrets through the Power Automate HTTP action, as the Power Automate Key Vault connector does not have an action for updating Key Vault secrets.

First navigate to the “App registration” service in Azure Portal and click on “New registration

When registering, make sure to give it a recognizable name to identify what it’s used for. In my case I called it “Key Vaults API”. Click on “Register” to finish.

Now that’ the App is created, let’s go ahead and configure the permissions to our Key Vaults service. Navigate to the “API permissions” and click on “Add a permission“.

A new “Blade” will pop up (I hate this reference), click on the “Azure Key Vault” service.

Add the permissions as seen above.

Now the last few configurations that we need before we’re done with the whole Key Vault thing… Save the Client secret value

Go to Overview tab and save the Application ID as well.

Navigate to the Key Vault page and create a new Access policy for our application. Go to “Access policies” and click on “Create”.

Set the minimal permissions needed for the application. We are only giving the API application the rights to “Get” and “Set” operators (only these are dependent for the rest of the tutorial).

Skip the optional part to get to “Review + create” and click “Create”.

You’ve now managed to setup your new Azure Key Vaults! Next up is creating the flow for auto-updating the token!


Creating the Power Automate flow to get the OAuth token and its lifecycle information

For this auto-update scenario, create a new flow that is specifically triggered by “Recurrence” and set it to any interval, as long as it does not interfere with our testing. Set it in the value of seconds (e.g. 100000 seconds). Additionally, add two new actions to get the Key Vault secrets, and then add an HTTP action to get the OAuth token from Discord. Use the secret values from the two Key Vault secrets actions for “client-id” and “client-credential” in the HTTP action.

The beginning of the flow should end up looking like this:

Now save and run the flow once. Copy the whole JSON body, and go back to edit this flow. The copied information will later be used to parse the response in the next step.

Back in “Edit” mode, add a “Parse JSON” action to the flow.

Click on the “Generate from sample” and paste it in the body copied from previous step. Before you finish, make sure to keep the expire_in value. Next, create a third Key Vault secret with an empty value, and then adjust the trigger recurrence value to match the expiration value. Now, you can save your flow if you haven’t done so already… ๐Ÿ’พ

Go back to Azure Key Vault and create the third key vault secret with an empty value.


Building the flow to update the access token value in Azure Key Vaults

Great! Now the last part that’s left is adding the things that will make this flow to automate itself.ย 

Now go back to edit the Power Automate flow and set the Trigger Interval to match your token’s expiration value from the same response. However, since I’m always on the safe side, I personally set it a bit shorter instead (e.g. 604740 seconds).

Add a “HTTP” action with POST method with the following information:

URI:

https://login.microsoftonline.com/{directory-tenant}/oauth2/v2.0/token

Header:

Content-Type = application/x-www-form-urlencoded

Body:

client_id={app_client_id}&client_secret={app_client_secret}&grant_type=client_credentials&scope=https://vault.azure.net/.default

Cool, now save the flow and run it. Again, we want the response body and parse it as well, generating from sample and then go back to edit mode.

Add a parse action. Content: Dynamic body value. Generate from sample: Paste in theย  body values in clear text from last run and click “Done”.

Now use the parsed outputs to update the Azure Key Vault secret “discord-api-oauth-token” as seen on the picture below:

URI:

https://{vault name}.vault.azure.net/secrets/{secret name}?api-version=7.3

Header:

Authorization = Bearer {token from previous HTTP call}

Body:

{

"value": "{new access token}

}

And last but not least, especially before you run the flow!…

Make sure your settings for all of the HTTP-actions has these settings turned on. It will hide the credential details in the logs.

Nice work! You’ve made it to the end of the tutorial! Now a quick recap!


Summary

We’ve successfully created an Azure Key Vault with secret values where we are storing our API credentials (client ids, client secrets, OAuth tokens)

  • We’ve successfully setup an API application with token through Azure AD App registration to use API calls with the Graph API serv.
  • We’ve successfully scheduled a Power Automate flow to update a Key Vault secret (in this case an OAuth token stored as a Key Vault Secret) independently. This means that all your future Power Automate flows will only need to relate to the token, without an authentication. This is especially great for big consulting companies with many different client credentials towards different services in-house – where a new developer only need to relate to the token instead, making it a more secure framework.

In my personal projects, I take advantage of the Key Vault so much that I don’t even need to remember the client_id or client_secret anymore and am only invoking the automatically updated token as seen on the example below. ๐Ÿ˜Ž

Comments

3 responses to “Power Automate: Store your API Access tokens in Azure Key Vaults and automatically renew them!”

  1. Sarah Avatar
    Sarah

    Thanks for this, the part where you update the secret via HTTP Put is exactly what I was looking for.

  2. Nick Thoman Avatar

    Perfect! Just Perfect! You need to post a Venmo QR Code so people can thank you. ๐Ÿ™‚

    One Question, do you know if there is a way to post the expiration date when you update the Secret via the API?

    1. gchi Avatar

      Hi, Nick!

      Sorry for the late response, been on a hiatus for a while now. But to respond to your question, I did a little digging and I think there’s an endpoint to change the Key Vault expiration date, see: Key Vaults – Update Key operation

      What this means is that you need to create a new HTTP action after updating, using the updated “expires in” information from the HTTP- Update Azure Key Vault and use that value to update the Key Vault “exp” key-value pair.

      Hope this would help.

Leave a Reply

Your email address will not be published. Required fields are marked *