-
Notifications
You must be signed in to change notification settings - Fork 4.6k
AWS IAM Auth: Support dynamic entity alias metadata from IAM role tags at login time #31864
Description
AWS IAM Auth: Support dynamic entity alias metadata from IAM role tags at login time
Is your feature request related to a problem? Please describe.
When using Vault's AWS IAM auth method at scale (hundreds of microservices), each service requires a dedicated Vault auth role and policy with hardcoded paths. This creates a significant operational burden, especially during service migrations (cross-account migration, IAM role renaming, infrastructure refactoring) — when an IAM role ARN changes, all associated Vault auth roles and policy bindings must be manually recreated.
In contrast, the Kubernetes auth method supports alias_metadata mapped from ServiceAccount labels, which allows a single Vault auth role and a single templated policy to serve all services dynamically. The AWS IAM auth method has no equivalent capability — entity alias metadata is limited to a fixed set of fields (account_id, auth_type, canonical_arn, etc.), with no way to populate custom metadata from the authenticating IAM role's AWS tags.
This makes it impossible to build a unified authorization model across Kubernetes and AWS IAM auth methods.
Describe the solution you'd like
Add a configuration option (e.g., iam_tag_metadata) on the AWS auth role that maps specified IAM role tag keys to entity alias metadata fields at login time.
Key insight: this has zero additional cost. When resolve_aws_unique_ids is enabled (the default), Vault already calls iam:GetRole on every IAM auth login. The GetRole response already contains the Tags field — it is simply not being used. This proposal reads an additional field from an existing API response, with no extra network call and no extra AWS API cost.
Example Configuration
vault write auth/aws/role/default \
auth_type=iam \
bound_iam_principal_arn="arn:aws:iam::123456789012:role/*" \
iam_tag_metadata="vault-service,vault-env"Example IAM Role Tags
vault-service = payment
vault-env = prod
Resulting Entity Alias Metadata at Login
{
"account_id": "123456789012",
"auth_type": "iam",
"canonical_arn": "arn:aws:iam::123456789012:role/payment-prod",
"vault-service": "payment",
"vault-env": "prod"
}Templated Policy
path "secret/data/{{identity.entity.aliases.auth_aws_xxxx.metadata.vault-service}}/{{identity.entity.aliases.auth_aws_xxxx.metadata.vault-env}}/*" {
capabilities = ["read"]
}Describe alternatives you've considered
-
Per-service Vault auth role + policy (current approach): Does not scale. Each service needs a dedicated Vault auth role and policy. Migration requires recreating all bindings.
-
Identity Groups with metadata: Assign entities to Vault identity groups with metadata, then use templated policies on groups. This requires creating and maintaining a group per service — at hundreds of services, the maintenance cost is even higher than per-service roles.
-
External automation (Lambda / CronJob) to sync AWS tags → Vault entity metadata: After IAM auth login, an external process reads IAM role tags via AWS API and writes them to Vault entity metadata. This works but introduces an external application with write access to Vault's identity system — a significant security risk and operational dependency.
-
Naming conventions in IAM role ARN + templated policies: Encode service/env info in the IAM role name, then use the
canonical_arnmetadata in templated policies. However, Vault's templated policies cannot perform string extraction or parsing, making this impractical.
None of these alternatives provide the simplicity and security of having Vault natively read IAM role tags at auth time — the same pattern that already works for Kubernetes auth.
Explain any additional use-cases
Migration without Vault-side changes
| Without this feature | With this feature | |
|---|---|---|
| Vault auth roles | Dedicated role per service | 1 wildcard-bound auth role, per-service authorization via templated policies |
| Vault policies | Dedicated policy per service | 1 templated policy (dynamically scoped by metadata) |
| Onboard new service | Create Vault auth role + policy | Add AWS tags to IAM role |
| Migrate service (new IAM role ARN) | Recreate or update Vault auth role + policy bindings | Add same AWS tags to new IAM role — zero Vault-side changes |
Unified authorization model across auth methods
Organizations running workloads on both Kubernetes and AWS can use the same templated policy pattern for both auth methods:
Kubernetes auth (today):
# 1. ServiceAccount with labels
apiVersion: v1
kind: ServiceAccount
metadata:
name: payment-service
labels:
vault-service: payment
vault-env: prod
# 2. One Vault auth role — alias_metadata maps SA labels to entity metadata
vault write auth/kubernetes/role/default \
bound_service_account_names="*" \
bound_service_account_namespaces="*" \
alias_metadata="vault-service,vault-env"
# 3. Templated policy — dynamically scoped by metadata
path "secret/data/{{identity.entity.aliases.auth_k8s_xxxx.metadata.vault-service}}/{{identity.entity.aliases.auth_k8s_xxxx.metadata.vault-env}}/*" {
capabilities = ["read"]
}
# Result: payment-service gets access to secret/data/payment/prod/*AWS IAM auth (proposed):
# 1. IAM role with tags
aws iam tag-role --role-name payment-service \
--tags Key=vault-service,Value=payment Key=vault-env,Value=prod
# 2. One Vault auth role — iam_tag_metadata maps IAM role tags to entity metadata
vault write auth/aws/role/default \
auth_type=iam \
bound_iam_principal_arn="arn:aws:iam::123456789012:role/*" \
iam_tag_metadata="vault-service,vault-env"
# 3. Same templated policy pattern
path "secret/data/{{identity.entity.aliases.auth_aws_xxxx.metadata.vault-service}}/{{identity.entity.aliases.auth_aws_xxxx.metadata.vault-env}}/*" {
capabilities = ["read"]
}
# Result: payment-service gets access to secret/data/payment/prod/*The authorization model is identical — the only difference is the metadata source (SA labels vs IAM role tags).
Additional context
Security Considerations
This feature extends the trust boundary: anyone with iam:TagRole permission on an IAM role could influence Vault authorization by modifying tags. This is the same trust model as the Kubernetes auth method, where anyone who can modify ServiceAccount labels can influence Vault authorization.
Recommended mitigations:
-
Vault side: The
iam_tag_metadataconfiguration should act as a whitelist — only explicitly listed tag keys are mapped to metadata. Unrecognized tags are ignored. -
AWS side: Use IAM policies to restrict who can create or modify tags with the designated prefix (e.g.,
vault-*):{ "Effect": "Deny", "Action": ["iam:TagRole", "iam:UntagRole"], "Resource": "*", "Condition": { "ForAnyValue:StringLike": { "aws:TagKeys": "vault-*" } } } -
Audit: Tag changes on IAM roles are logged in AWS CloudTrail, providing a clear audit trail.
Implementation Note
Since Vault already calls iam:GetRole when resolve_aws_unique_ids=true (the default), the implementation would only need to:
- Add an
iam_tag_metadatafield to the AWS auth role configuration (list of allowed tag keys) - Read the
Tagsfield from the existingGetRoleresponse - Populate matching tags into the entity alias metadata
No new AWS API calls, no new IAM permissions required.
References
- Kubernetes auth
alias_metadata: https://developer.hashicorp.com/vault/api-docs/auth/kubernetes - AWS auth
iam:GetRolerequirement: https://developer.hashicorp.com/vault/docs/auth/aws - AWS
GetRoleAPI response includesTags: https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRole.html