Ep 41 | Unlock Growth in the Nonprofit Market with AI, Security, and Microsoft Elevate
June 29, 2026Find and fix app issues - Azure Copilot Observability Agent
June 29, 2026
What you will learn:
- What Workload Identity Federation is and how it works
- How to set up trust between AWS and Microsoft Entra ID
- How to exchange AWS identity tokens for Azure access tokens
- How to securely call an Azure Function from AWS without storing credentials
This approach improves security, removes secret management overhead, and aligns with Zero Trust principles.
Let’s start by understanding why this approach is needed in a multi-cloud environment.
Why this approach is needed
In today’s multi-cloud landscape, organizations frequently need to connect services across cloud providers like AWS and Azure.
Traditionally, this required storing long-lived Azure client secrets within AWS environments. While functional, this introduces:
- Security risks (secrets can leak or be misused)
- Operational overhead (secret rotation and storage)
- Increased maintenance complexity
Microsoft Entra ID provides a modern alternative: Workload Identity Federation, which eliminates the need for static credentials entirely.
What is Workload Identity Federation?
Workload Identity Federation is a feature in Microsoft Entra ID that allows you to trust identities from external providers like AWS, GCP, or GitHub. Instead of a secret, Azure validates the identity of the AWS resource based on its own native OIDC (OpenID Connect) token.
This approach is particularly useful for:
- Securing Cross-Cloud Pipelines: Enabling AWS Lambda or EC2 to call Azure APIs without managing keys.
- Eliminating Secret Rotation: Removing the need to update expired secrets across different cloud providers.
- Enhancing Security: Using short-lived, verifiable claims that automatically expire.
In this blog, we will cover the configuration for service-to-service authentication and user-led validation for troubleshooting. The following guide outlines the complete technical configuration required to implement this architecture.
An overview of what we will be doing:
- Generate AWS Token: Your AWS resource (Lambda, EC2, etc) generates a short-lived OIDC token signed by AWS.
- Exchange for Azure Token: The AWS token is sent to Microsoft Entra ID. Azure validates the AWS signature using your Federated Credential and issues a native Azure Access Token in return.
- Attach Verified Permissions: We configure an App Role on the Function App and link it to our Caller App. This helps Azure identify the correct permissions to inject into the token, confirming the caller is officially permitted to access your API.
- Authorize Azure Function: The AWS resource calls the Function URL with the Azure token. The Function’s authentication layer verifies the token’s claims and grants access.
Section 1: AWS side setup
Step 1–Enabling Outbound Identity Federation
- Go toIdentity and Access Management (IAM)-> Access Management->Account Settings
- Scroll down to the Outbound Identity Federation section and enable it. Note down the Token Issuer URL—we will use it later to set up the Issuer claim in the federated credentials on the Azure side.
Step 2– Create a role for your AWS resource (Lambda, EC2)
- Go to Identity and Access Management (IAM) -> Access Management->Roles
- Click on the Create role button on the top right and select the trusted entity type, I selected AWS service. For use case I selected EC2.
- Under Permissions, click Add permissions > Create inline policy.
- Switch to the JSON tab and paste this:
curl -X POST
“https://login.microsoftonline.com//oauth2/v2.0/token”
-H “Content-Type: application/x-www-form-urlencoded”
-d “client_id= ”
-d “scope=api:// /.default”
-d “grant_type=client_credentials”
-d “client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer”
-d “client_assertion= “ - Review and Save (name it something like AllowSelfWebIdentityToken). This permission allows the role to generate its own OIDC token for external exchange (you can do this step after the creation of role as well by editing the role)
- I named the role aws-federation-role. Review and create the role. After the creation is complete note down the ARN for the role.
Section 2: Azure side setup
Step 3 — Register the AWS Caller App in Entra ID
This registration represents the AWS resource that will request a token and call your API in the Azure side.
- Go to Azure Portal → Microsoft Entra ID → App registrations → + New registration. Fill in the following details:
- Name: aws-caller-app
- Supported account types: Single tenant (your tenant)
- Click Register. Now you’ll see Application (client) ID and Directory (tenant) ID. Copy both — you’ll need them later.
Step 4— Create Federated Credentials
This allows AWS to impersonate this application by establishing a trust with an external OpenID Connect (OIDC) identity provider and get tokens to access Microsoft Entra ID resources.
- In the aws-caller-app that you just created, go to Manage->Certificates and Secrets. Go to the Federated credentials section on the page.
- Fill the following details:
- Federated credential scenario: Other issuer
- Issuer: Add the Token Issuer URL that we copied in Step 1 from AWS.
- Type: Explicit subject identifier
- Value: Add the ARN of the AWS resource that we copied in Step 2
- Name: aws-federation
- Add Description and leave the Audience claim as is. Click Add.
Step 5— Register your Function App in Entra ID
This registration represents the Function App resource that will receive a token and be called on the Azure side. My Function App is an API called aws-entra-federation-api.
- Go to Azure Portal → Microsoft Entra ID → App registrations → + New registration. Fill in the following details:
- Name: function-api-app
- Supported account types: Single tenant (your tenant)
- Click Register. Now you’ll see Application (client) ID and Directory (tenant) ID. Copy both — you’ll need them later.
Step 6– Create an App Role in function-api-app
App roles are custom role templates which define permissions that can be assigned to users or apps.
- In the function-api-app that you just created, go to Manage → App Roles in the left menu.
- Create a new Role and fill the following details:
- Display Name: access_as_app
- Allow Member Types: Applications
- Value: access_as_app
- Description: Allow application to application access
- Do you want to enable this app role?: True (Checked)
- Click “Apply”.
Step 7– Assign API Permissions to the aws-caller-app
In the previous step we created a role on the function-api-app, now we will assign this role to the aws-caller-app so that it is able to authorize and call the function-api-app.
- In the function-api-app, go to Manage → API Permissions in the left menu.
- Click “+ Add a permission”. Click on the “APIs my organization uses” tab.
- In the search bar, enter the name of the app/service principal created before function-api-app.
- Select Application permissions and, under the Permissions section, choose the role created before (access_as_app).
- Click the “Add permissions” button.
- Back in the Manage → API Permissions screen, click “Grant admin consent for Default Directory“.
Step 8— Configure Authentication on the Azure Function resource (aws-entra-federation-api)
Enable authentication on your function resource (aws-entra-federation-api) and link it to the app registration (function-api-app) you created earlier.
- Go to your Function App resource in the Azure Portal
(aws-azure-federation-api) - On the left menu, select Authentication.
- Click + Add identity provider. Add the following details:
- Identity provider: Microsoft
- App registration type: Provide details of an existing app registration
- Client ID: Paste the Application (client) ID of your function-api-app from step 5(APP_URI)
- Issuer URL: https://login.microsoftonline.com//v2.0 (Replace with your Directory (tenant) ID)
- Client application requirement: Allow requests from any application
- Identity requirement: Allow requests from any identity
- Tenant requirement: Allow requests only from the issuer tenant
- Under Restrict access, select Require authentication
- Unauthenticated requests: HTTP 401
- Any other field not listed should remain as default. Click “Add” and refresh the Settings → Authentication view.
- The new configured provider will appear. Click “Edit”. A list of fields will appear. Make the following changes:
- Allowed token audiences: Lets consider Application ID for function-api-app from step 5 as the value for variable APP_URI. Add the following three different audiences.
- api://
- api:// /.default
- Any other field not listed should remain as default. Save the changes. Now the Function App will only accept calls with valid Azure AD access tokens.
Congratulations, you have successfully completed the setup required for using Federated Identity authentication. Now let’s test if the setup is working correctly.
Section 3: Validating the setup
Step 9 – Requesting Azure token and authenticating to the function app.
In my case, I’ve logged in to my AWS account using my user account (not root user) and then opened AWS CloudShell. I will be validating the setup through user account as I have not deployed any AWS resource. You should be able to request for Azure token through Lambda or other AWS resource in a similar manner.
We will be using the following variable and values in the following steps:
- ARN: The ARN of the role created in step 2 on AWS.
- TENANT_ID: Your Azure tenant ID, you can find this by going to your Account->All directories and copy the Directory ID
- CLIENT_ID: The application (object) ID of the app registration created for the AWS caller app generated in step 3(aws-caller-app, in this case).
- APP_URI: The application (object) ID of the App registration created for the function app resource generated in step 5 (function-api-app, in this case).
- DEFAULT_DOMAIN: You can find this in the overview section of your Azure Function app resource (aws-entra-federation-api, in this case).
We need to follow a few extra steps because this validation uses a user account. In production, the AWS SDK performs the ‘identity proofing’ step (step 4) for you. In your code, you simply take that identity, exchange it for an Azure token at the Microsoft Entra endpoint, and use the token to call your Azure Function. As a result, a production workload typically doesn’t need the first four steps.
- Assume the Role that was created earlier for the AWS resource in Step 2, we are logged in to the AWS CloudShell with the user account but we need to use the role that we created earlier to generate AWS token and exchange it for Azure token. aws sts assume-role –role-arn
- As output, we get accesskeyid, secretaccesskey and sessiontoken. We will be using these as variables in the next step.
- Set these values as variables:
export AWS_ACCESS_KEY_ID=” ”
export AWS_SECRET_ACCESS_KEY=” ”
export AWS_SESSION_TOKEN=””
- Generate the AWS OIDC Token that is specifically formatted for Azure.
aws sts get-web-identity-token
–audience “api://AzureADTokenExchange”
–signing-algorithm “RS256”
–duration-seconds 3600 - We get the WebIdentityToken in the output. Store it as we will be using it in the next step.
- Now we will exchange the AWS token (WebIdentityToken) for an Entra ID token
curl -X POST
“https://login.microsoftonline.com//oauth2/v2.0/token”
-H “Content-Type: application/x-www-form-urlencoded”
-d “client_id= ”
-d “scope=api:// /.default”
-d “grant_type=client_credentials”
-d “client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer”
-d “client_assertion= ”
- We get the access_token as the output of the last step. Store it as we will be using it in the next step.
- Use the Entra ID token from the last step to send a request to your app—in this case, the function-api-app.
curl -X GET “https:// ”
-H “Authorization: Bearer ”
-H “Content-Type: application/json”
- You should get a 200 OK response.
Conclusion
By implementing Workload Identity Federation, you have moved away from the “Secret Management” era of cloud security. Instead of worrying about rotating client secrets or securing them in a vault, you are now using a short-lived, verifiable trust relationship between AWS and Azure.
What’s Next?
Now that your authentication is secure, you can explore:
- Fine-Grained Authorization: Use the claims inside the Azure Access Token to restrict specific actions within your Azure Function code.
- Conditional Access Policies: Layer on Azure Conditional Access to ensure requests only come from trusted locations, such as your specific AWS VPC or a designated IP range.
- Automating with Terraform/Bicep: Now that you’ve done it manually, consider codifying this setup to ensure consistent security across all your environments.