Using AWS Outbound Identity Federation for Azure Resources

Published: (December 19, 2025 at 12:30 PM EST)
5 min read
Source: Dev.to

Source: Dev.to

AWS Identity Federation Limitations

Unlike Google Cloud’s workload identity pool AWS provider, Azure managed identity does not support IAM authentication with pre‑signed URLs. Azure managed identity only supports external OpenID Connect (OIDC) providers, which means that workloads running in AWS could not federate into an Azure environment without using another service that can convert OIDC tokens (e.g., AWS EKS or Cognito).

Up until now, the Puma Security Nymeria cross‑cloud workload identity project had examples for federating from AWS Lambda functions and EKS pods into both Azure and Google Cloud storage resources. With the 2025 re:Invent release of IAM Outbound Identity Federation, we’ve added support for an AWS EC2 instance to federate into an Azure storage resource.

The diagram below illustrates the architecture for an AWS EC2 instance using AWS Outbound Identity Federation to access an Azure Blob storage container. The EC2 instance requests a signed OIDC token from AWS IAM via the sts:GetWebIdentityToken API. The AWS‑signed OIDC token is then used to log in to the Azure tenant’s user‑assigned managed identity, after which the EC2 instance can obtain an Azure access token and access the storage container and blob objects.

Nymeria AWS IAM Outbound Identity Federation

AWS Outbound Identity Federation Setup

Before you can use the feature, you must enable Outbound Identity Federation in your AWS account. This can be done via the AWS Management Console or with the Terraform provider (v6.26.0 or later) using the new aws_iam_outbound_web_identity_federation resource:

# Enables account‑level web identity federation
resource "aws_iam_outbound_web_identity_federation" "this" {}

After applying the configuration, the AWS IAM console shows that Outbound Identity Federation is enabled and a unique Token Issuer URL is generated for your account. This URL will be needed later when configuring the Azure managed identity’s trust relationship.

AWS IAM Outbound Identity Federation Configuration

AWS Outbound Identity Federation Permissions

To use the feature, create an IAM role (and an instance profile) for the EC2 instance. The role must include the sts:GetWebIdentityToken permission.

Terraform – IAM policy document

data "aws_iam_policy_document" "cross_cloud" {
  statement {
    sid    = "AllowTokenVending"
    effect = "Allow"
    actions = [
      "sts:GetWebIdentityToken",
    ]
    resources = [
      "*",
    ]
  }
}

resource "aws_iam_policy" "cross_cloud" {
  name        = "nymeria-cross-cloud-token-${random_string.unique_id.result}"
  path        = "/"
  description = "IAM policy for Nymeria VM"
  policy      = data.aws_iam_policy_document.cross_cloud.json

  tags = {
    Product = "Nymeria"
  }
}

Requesting a token from the EC2 instance

Connect to the instance (via SSM Session Manager or SSH) and run the following AWS CLI command:

aws sts get-web-identity-token \
    --audience api://AzureADTokenExchange \
    --signing-algorithm RS256 \
    --duration-seconds 300

The command returns JSON similar to the snippet below. The WebIdentityToken field contains the signed OIDC token, and the Expiration field shows the token’s expiry time.

{
  "WebIdentityToken": "",
  "Expiration": "2025-12-20T12:34:56Z"
}

You can now exchange this token with Azure AD to obtain an Azure access token and access the desired Azure Blob storage resources.

{
  "IdentityToken": "eyJraWQiOiJSU0FfMCIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0...",
  "Expiration": "2025-12-19T04:06:07.577000+00:00"
}

Azure Managed Identity Configuration

Now that we know how to request an AWS outbound identity token, we can configure the Azure managed identity to trust the AWS outbound identity provider. This involves extracting the necessary claims from the AWS identity token and using those claims to configure the Azure managed identity’s federated credentials.

AWS Outbound Identity Token Claims

Start by decoding the AWS identity token using jq. We need the token’s iss (issuer) and sub (subject) claims to configure the Azure managed identity’s trust relationship.

JWT=$(aws sts get-web-identity-token \
          --audience api://AzureADTokenExchange \
          --signing-algorithm RS256 \
          --duration-seconds 300 | jq -r '.WebIdentityToken')

Note: Azure’s managed identity federation does not support advanced claim filters, such as those found in the https://sts.amazonaws.com/ claim. Only the iss, aud, and sub claims are needed when configuring Azure managed identity trust.

{
  "aud": "api://AzureADTokenExchange",
  "sub": "arn:aws:iam::123456789012:role/nymeria-cross-cloud-9zo9h8c5",
  "https://sts.amazonaws.com/": {
    "ec2_instance_source_vpc": "vpc-1234567890123456",
    "ec2_role_delivery": "2.0",
    "org_id": "o-abcd1234",
    "aws_account": "123456789012",
    "ou_path": [
      "o-abcd1234/r-abc/ou-abc-def/"
    ],
    "original_session_exp": "2025-12-19T10:21:06Z",
    "source_region": "us-east-2",
    "ec2_source_instance_arn": "arn:aws:ec2:us-east-2:123456789012:instance/i-12345678901234567",
    "principal_id": "arn:aws:iam::123456789012:role/nymeria-cross-cloud-9zo9h8c5",
    "principal_tags": {
      "Product": "Nymeria"
    },
    "ec2_instance_source_private_ipv4": "10.142.128.107"
  },
  "iss": "https://53e20c38-5c03-41f7-8baa-a67e81974de0.tokens.sts.global.api.aws",
  "exp": 1766118898,
  "iat": 1766118598,
  "jti": "1640bab7-b35b-4410-b4ee-04d219abbf33"
}

Azure Managed Identity Trust Configuration

To establish trust in the Azure tenant, start by creating a user‑assigned managed identity in a resource group with permissions to read data from the cross‑cloud storage account.

Terraform – Managed Identity & Role Assignment

resource "azurerm_user_assigned_identity" "cross_cloud" {
  name                = "cross-cloud-vm-${random_string.unique_id.result}"
  location            = var.location
  resource_group_name = azurerm_resource_group.federated_identity.name
}

resource "azurerm_role_assignment" "cross_cloud_blob_reader" {
  principal_id         = azurerm_user_assigned_identity.cross_cloud.principal_id
  scope                = azurerm_storage_account.cross_cloud.id
  role_definition_name = "Storage Blob Data Reader"
}

Terraform – Federated Credential

Configure the user‑assigned managed identity’s federated credentials to trust the AWS outbound identity provider.

resource "azurerm_federated_identity_credential" "aws" {
  name                = "nymeria-aws"
  resource_group_name = var.azure_resource_group_name
  parent_id           = var.azure_managed_identity_id

  issuer   = var.aws_account_issuer
  audience = ["api://AzureADTokenExchange"]
  subject  = var.aws_iam_role_arn
}
  • var.aws_account_issuerhttps://53e20c38-5c03-41f7-8baa-a67e81974de0.tokens.sts.global.api.aws
  • var.aws_iam_role_arnarn:aws:iam::123456789012:role/nymeria-cross-cloud-9zo9h8c5

Accessing Azure Blob Storage from AWS EC2

With the federation and trust relationship configured, the EC2 instance can now access the Azure Blob storage container.

  1. Request a new AWS outbound identity token and store it in an environment variable called JWT.

    JWT=$(aws sts get-web-identity-token \
            --audience api://AzureADTokenExchange \
            --signing-algorithm RS256 \
            --duration-seconds 300 | jq -r '.WebIdentityToken')
  2. Export the required Azure variables:

    export AZURE_TENANT_ID="your-azure-tenant-id"
    export AZURE_MANAGED_IDENTITY_CLIENT_ID="your-managed-identity-client-id"
    export AZURE_STORAGE_ACCOUNT="your-storage-account-name"

Authenticate to Azure with the AWS Outbound Identity Token

az login \
  --service-principal \
  --tenant $AZURE_TENANT_ID \
  --username $AZURE_MANAGED_IDENTITY_CLIENT_ID \
  --federated-token $JWT

The command returns a JSON block confirming successful authentication.

List Blobs in the Azure Storage Container

az storage blob list \
  --auth-mode login \
  --account-name $AZURE_STORAGE_ACCOUNT \
  --container-name assets \
  | jq '.[].name'

The output lists the blob names, confirming that access to the storage account is working as expected.

Conclusion

AWS IAM Outbound Identity Federation provides a new way for workloads running in AWS to securely access external cloud resources using short‑lived, signed OIDC tokens. With this feature, the Puma Security Nymeria cross‑cloud workload identity project now supports federating from AWS EC2 instances into both Azure and Google Cloud storage resources.

References

About the Author

Eric Johnson – LinkedIn profile
Eric’s experience includes cloud security architecture and design, cloud‑native and Kubernetes assessments, infrastructure‑as‑code automation, application security automation, web and mobile application penetration testing, secure development lifecycle consulting, and secure code‑review assessments.

Back to Blog

Related posts

Read more »

Unauthenticated APIs Report

Overview A security automation tool that scans API endpoints to identify unauthenticated access vulnerabilities. It tests various HTTP methods and authenticati...

AWS Orphan Alarms Report Generation

Pipeline Configuration Options - Build Discarder: Keeps the last 5 builds and artifacts. - Timestamps: Adds timestamps to the build log. Environment Variables...

AWS Backup Failed Monitoring

markdown !Prashant Guptahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%...