This repo shows an example of how to use Logic Apps to regenerate the primary key in an Azure API Management instance. APIM doesn't provide a native way to rotate keys on a regular basis. Rotating API subscription keys is a good security practice since they are just a long password and should not be considered a secure method of authorizing API calls.
This repo also has an example of how to use Logic Apps in combination with an Azure Function and an Azure Key Vault to generate custom API subscription keys, store them in Key Vault and then set the key in APIM.
This repo also shows you how to use stateful Logic Apps to notify subscription owners that their API subscription keys are about to expire and ask them to approve or deny being the owner.
This repo also shows you how to build a simple web app that has a user interactively sign-in and then call an API protected via the OAuth2 validate-jwt token policy. There is also an example of a daemon (background process with no user interactively signed in) accessing this same API. The APIM policy will also log the Application ID
of the calling AAD application and log the request to Azure Event Hub for further processing.
In both cases, the APIM & backing API don't know or care about how the calling application authenticated & got an access token (either via Authorization Code Flow or Client Credential Flow). The same validate-jwt
policy can be used for both.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Azure subscription & resource group
- Azure CLI
- dotnet CLI
- .NET 6
- Azure Function CLI
- PowerShell
- Visual Studio Code
- Logic Apps Visual Studio Code Extension
- Event Hub Visual Studio Code Extension
-
Open the
Azure Active Directory
blade in the Azure portal -
Click on the
App Registration
blade & click onCreate
-
Give it a human-readable name like
logic-apim-key-backend-api
. You don't need to set areply uri
at this time. -
Take a note of the
TenantId
on theOverview
blade. You will need this value to correctly set up the APIMvalidate-jwt
policy. -
Take a note of the
Application Id
that is generated on theOverview
blade. You will need this value to correctly set up the APIMvalidate-jwt
policy to look for the correctaudience
. -
On the
Expose an API
blade, click onAdd a scope
. Accept the defaultApplication ID URI
. Add a scope calleduser_impersonation
. Make a note of theApplication ID URI
. You will need it when deploying the Azure Resource Manager scripts. -
On the
App roles
blade, click onAdd an app role
. Create a newApp Role
calledaccess_as_user
and selectApplication
as the type.
-
Open the
Azure Active Directory
blade in the Azure portal -
Click on the
App Registration
blade & click onCreate
-
Give it a human-readable name like
logic-apim-key-backend-api
. Set thereply uri to type
Weband the value to
https://localhost:7071/signin-oidc`. -
Note the
Application (client) ID
&Directory (tenant) ID
. You will need these values when configuring the api app. -
On the
Certificates and secrets
blade, create a new secret for the client API to use to authenticate (using Authorization Code Flow). -
On the
API permissions
blade, clickAdd a permission
. -
Select
My APIs
and select your backend API. Select theDelegated permissions
button and then check the box for theuser_impersonation
scope you created earlier. -
Click
Add permissions
.
-
Open the
Azure Active Directory
blade in the Azure portal -
Click on the
App Registration
blade & click onCreate
-
Give it a human-readable name like
logic-apim-key-backend-api
. Set thereply uri
type toWeb
and the value tohttps://localhost:7071
. -
Note the
Application (client) ID
&Directory (tenant) ID
. You will need these values when configuring the client web app. -
On the
Certificates and secrets
blade, create a new secret for the client API to use to authenticate (using Client Credential Flow). -
On the
API permissions
blade, clickAdd a permission
. -
Select
My APIs
and select your backend API. Select theApplication permissions
button and then check the box for theaccess_as_user
scope you created earlier. -
Click
Add permissions
. -
Click on
Grant admin consent for <tenant_name>
. This will allow the client API app to access the backend API. Note that you will needglobal admin
to consent.
-
Modify the
infra/env/dev.parameters.json
file as needed for your environment. -
Execute the following Azure CLI from the root directory of the repo (substituting your values as needed)
az deployment group create -g rg-logic-apim-key-ussc-demo --template-file ./infra/main.bicep --parameter ./infra/env/dev.parameters.json --parameter publisherName=dwight publisherEmail=dwight.k.schrute@dunder-mifflin.com tenantId=5bd0289f-3c17-4315-96eb-0e2116fa49fc apiAppIdUri=api://34930f13-7679-40f5-9313-1b6c07dc4c09
-
Deploy the Azure Function code (substituting your Azure Function name as needed).
cd ./web/generate-new-subscription-key-function func azure functionapp publish func-logicApimKey-ussc-demo
-
Zip up & deploy the Logic App workflows (substituting your values as needed). Change
Compress-Archive
if needed on Linux.Compress-Archive -Path ./logic-app/* -DestinationPath ./logic-app.zip -Update az logicapp deployment source config-zip --name logic-logicApimKey-ussc-demo --resource-group rg-logic-apim-key-ussc-demo --subscription <subscription-name> --src ./logic-app.zip
You will need to open each Logic App workflow in the Azure portal and initialize it using your credentials to send email.
-
Open the
Logic App
in your Resource Group. -
Click on the
Workflows
blade -
Select the
notify-subscription-owner
workflow -
Click on the
Designer
blade -
Select the
Send an email
command of theOffice 365 Outlook
action. -
Click on the
Change connection
link and sign-in to use your credentials to send emails. -
Repeat these steps for the other
Send an email
actions in this workflow & the other 2 workflows everywhere theSend email
command is used.
The Logic App will go through the following steps to regenerate the API subscription primary key when it is within 30 days of expiring and then notifying the owner.
-
It will first query the APIM to see what API subscriptions are expiring in the next 30 days.
-
It will then loop over each one and:
-
Regenerate the primary key using the native API for APIM.
-
Get the subscription owner ID & product name.
-
Send an email to the subscription owner notifying them of the change.
-
You can right-click on the logic-app/rotate-subscription-key/workflow.json
file and select Open in Designer
to see the GUI tool for building Logic Apps.
How to use Logic Apps to regenerate API subscription keys via an Azure Function, store that new key in Azure Key Vault & set the new key in APIM
The Logic App will go through the following steps to generate a new API subscription primary key when it is within 30 days of expiring, saving it to Key Vault & then setting it in APIM, and then notifying the owner.
-
It will first query the APIM to see what API subscriptions are expiring in the next 30 days.
-
It will then loop over each one and:
-
Call the Azure Function to generate a new primary key
-
Save this new key to Azure Key Vault.
-
Set the the primary key using the native API for APIM.
-
Get the subscription owner ID & product name.
-
Send an email to the subscription owner notifying them of the change.
-
You can right-click on the logic-app/set-subscription-key/workflow.json
file and select Open in Designer
to see the GUI tool for building Logic Apps.
The Logic App will go through the following steps to notify the API subscription owner of the API subscription key expiring and wait on their response (using stateful Logic Apps).
-
It will first query the APIM to see what API subscriptions are expiring in the next 30 days.
-
It will then loop over each one and:
-
Get the subscription owner ID & product name.
-
Send an email to the subscription owner notifying them of the expiration and asking them to
Approve
orDeny
. -
The Logic App will then wait on their response.
-
Based upon the response, it will send a follow-up email with an
Approval
orDenial
email.
-
You can right-click on the logic-app/notify-subscription-owner/workflow.json
file and select Open in Designer
to see the GUI tool for building Logic Apps.
-
Open VS Code.
-
Open the
Command Palette
(Ctrl+Shift+P
) and type inEventHub: Select EventHub
. Select your Event Hub. -
Open the
Command Palette
(Ctrl+Shift+P
) and type inEventHub: Start Monitoring Event Hub Message
.This will open the
Azure Event Hub Explorer
Output window.As you run each app, you will see the output from the Event Hub logger policy in APIM, capturing the
appid
field.
-
Update the
/web/client/user/appsettings.json
file with your local values.- You can get a
EchoAPISubscriptionKey
from the Azure portal. Open theAPI Management
instance and click on thesubscriptions
blade. Select aProduct
and click on the ellipsis, then click onShow/hide keys
.
- You can get a
-
Run the .NET code
dotnet run --project ./web/client/user
-
Run the
Azure Event Hub Explorer
to see the messages being sent to theeh-logicApimKey-ussc-demo
topic. -
Open a browser to the default address (https://localhost:7071)
-
Sign-in if prompted
-
Click on the
Call API
button -
Notice the values that have been sent to the Event Hub from your policy in APIM.
-
Update the
/web/client/api/appsettings.json
file with your local values.- You can get a
EchoAPISubscriptionKey
from the Azure portal. Open theAPI Management
instance and click on thesubscriptions
blade. Select aProduct
and click on the ellipsis, then click onShow/hide keys
.
- You can get a
-
Run the .NET code
dotnet run --project ./web/client/api
-
Run the
Azure Event Hub Explorer
to see the messages being sent to theeh-logicApimKey-ussc-demo
topic. -
Open a browser to the default address (https://localhost:7108)
-
Sign-in if prompted
-
Change the URL to the API endpoint (https://localhost:7108/vehicle)
-
Notice the values that have been sent to the Event Hub from your policy in APIM.