The most surprising thing about Vault’s AWS IAM authentication is that it doesn’t actually talk to AWS IAM to verify identities at runtime.

Let’s see this in action. Imagine you have an EC2 instance that needs to authenticate to Vault. First, you’d configure Vault’s AWS auth method. This involves telling Vault which AWS IAM role(s) are allowed to authenticate.

# Enable the AWS auth method
vault auth enable aws

# Configure an IAM role that can authenticate
# This role ARN is what Vault will check against when a token is generated.
# It's NOT used for the actual authentication step itself.
vault write auth/aws/config \
    iam_roles="arn:aws:iam::123456789012:role/my-vault-auth-role"

When your EC2 instance (or Lambda function) runs, it’s typically configured with an IAM instance profile (for EC2) or an execution role (for Lambda). This role has permissions to call sts:GetCallerIdentity. This is the only AWS API call your application needs to make.

Your application, using a Vault client library, will then initiate the authentication process. It calls sts:GetCallerIdentity to get its own AWS Account ID and IAM Role ARN.

import boto3
import hvac

# Get AWS identity
sts_client = boto3.client("sts")
identity = sts_client.get_caller_identity()
account_id = identity["Account"]
arn = identity["Arn"] # This will be the IAM role ARN

# Authenticate to Vault
client = hvac.Client(url="http://vault.example.com:8200")

# The 'role' here is a Vault-specific role, not the AWS IAM role directly.
# This role maps to the allowed AWS IAM roles configured in Vault.
try:
    response = client.auth.aws.login(
        role="my-vault-app-role", # This is a Vault role, not the AWS IAM role ARN
        iam_security_token="", # Leave empty if using instance profile/execution role
        # For EC2/ECS, you might need to provide the EC2 instance identity document
        # ec2_instance_identity_document=get_ec2_instance_identity_document()
    )
    vault_token = response["auth"]["client_token"]
    print(f"Successfully authenticated to Vault. Token: {vault_token}")
except Exception as e:
    print(f"Vault authentication failed: {e}")

The Vault client library then takes the ARN and the security token (if provided) and sends it to Vault. Vault’s AWS auth method doesn’t make an API call to AWS STS. Instead, it uses the pre-configured IAM role ARN that was given to it during the vault write auth/aws/config step. Vault checks if the ARN provided by the client matches one of the allowed ARNs it already knows about.

The iam_roles parameter in the vault write auth/aws/config command is crucial. It’s a list of IAM role ARNs that Vault is authorized to issue tokens for. When a client authenticates, Vault checks if the IAM role ARN it received is present in this configured list. If it is, and if the role parameter in the client.auth.aws.login call maps to this AWS IAM role (via a vault write auth/aws/role/<role-name> configuration), then Vault issues a token.

This mental model is key:

  • Problem Solved: Securely granting EC2 instances and Lambda functions access to Vault without embedding long-lived AWS credentials in your application or infrastructure.
  • How it Works Internally:
    1. Vault Configuration: You enable the AWS auth method and define which AWS IAM roles are allowed to authenticate and how they map to Vault roles.
    2. Application Setup: Your EC2 instance or Lambda function is given an IAM role with sts:GetCallerIdentity permission.
    3. Client Authentication: The application uses the AWS SDK to call sts:GetCallerIdentity to get its own identity (Account ID, IAM Role ARN).
    4. Vault Token Request: The application’s Vault client sends its IAM Role ARN and a Vault-specific role name to Vault.
    5. Vault Verification: Vault’s AWS auth method checks if the provided IAM Role ARN is in its list of allowed roles (from auth/aws/config) and if the Vault role name is correctly configured to map to that AWS IAM role (via auth/aws/role/<role-name>).
    6. Token Issuance: If all checks pass, Vault issues a short-lived Vault token, which the application then uses to access secrets.

The critical piece that most people miss is that Vault doesn’t dynamically verify the IAM role with AWS at the time of login. It relies on the fact that the EC2 instance or Lambda function already possesses the IAM role, and it trusts that the sts:GetCallerIdentity call accurately reflects the identity of the workload. The security relies on the IAM role’s permissions and the security of the underlying AWS infrastructure. Vault’s role is to map these trusted AWS identities to Vault’s own access control policies.

Once you’ve successfully logged in using AWS IAM auth, the next step is to understand how to manage the policies associated with the Vault tokens that are issued.

Want structured learning?

Take the full Vault course →