Gerador de AWS IAM Trust Policy
Gera o JSON de uma Trust Policy AWS IAM para Lambda, EC2, ECS e outros serviços. Define quem pode assumir a role criada.
Trust policies do AWS IAM: quem pode assumir o role
Uma trust policy é um documento JSON anexado a um IAM Role que responde uma pergunta só: "quem pode assumir esse role?". É distinta da permission policy, que responde "o que esse role pode fazer depois de assumido". Todo role IAM tem exatamente uma trust policy e uma ou mais permission policies — as duas são obrigatórias para o role ser útil.
Trust policies parecem policies IAM normais mas sempre têm um campo Principal (policies identity-based não têm) e a Action é quase sempre sts:AssumeRole (ou sts:AssumeRoleWithSAML / sts:AssumeRoleWithWebIdentity para principals federados).
Anatomia de uma trust policy
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
O exemplo acima é o trust típico de instance profile do EC2: o EC2 pode chamar sts:AssumeRole neste role para entregar credenciais temporárias a uma instância em execução. Troque ec2.amazonaws.com por lambda.amazonaws.com e vira role de execução do Lambda; por ecs-tasks.amazonaws.com, vira task role do ECS.
Tipos de Principal
- Service: principal de serviço AWS —
ec2.amazonaws.com,lambda.amazonaws.com,ecs-tasks.amazonaws.com, etc. Usado em instance profiles e execution roles. - AWS account:
"AWS": "arn:aws:iam::ACCOUNT_ID:root"confia em qualquer principal daquela conta, ou um ARN específico de user/role para apertar. Base de cross-account access. - Federated: provedores de identidade SAML ou OIDC — usado por GitHub Actions OIDC, Auth0, Okta, Google Workspace. A
Actionvirasts:AssumeRoleWithSAMLousts:AssumeRoleWithWebIdentity. - CanonicalUser: ID canônico legado do S3 — raramente usado em policies novas.
Conditions: os guardrails de segurança
sts:ExternalId— obrigatório em trust cross-account para vendor SaaS. Previne o ataque de confused-deputy em que o vendor é enganado para operar na conta errada.aws:PrincipalOrgID— restringe a assunção a principals dentro da sua AWS Organization.aws:SourceAccount+aws:SourceArn— prevenção de confused-deputy quando um serviço (S3, SNS) chama outro em seu nome.token.actions.githubusercontent.com:sub— para GitHub Actions OIDC, prende o role a um repo / branch / environment específicos via subject claim do token OIDC.aws:MultiFactorAuthPresent— exige MFA na sessão chamadora antes doAssumeRolepassar.
Padrão de cross-account
Duas peças são necessárias, uma em cada conta:
// Conta A — trust policy do RoleA
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::ACCOUNT_B:role/RoleB" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "segredo-compartilhado-unico" }
}
}
// Conta B — permission policy no RoleB
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT_A:role/RoleA"
}
Sem as duas metades, a chamada falha. A condition de ExternalId é inegociável em trust de terceiros (SaaS) — a própria AWS alerta sobre o risco de confused-deputy na doc.
GitHub Actions OIDC e IRSA
O GitHub Actions OIDC permite que um workflow assuma um role da AWS sem guardar chaves de longa duração como secret no repositório. Você cadastra o provider OIDC (token.actions.githubusercontent.com) no IAM uma vez e depois confia nele com uma condition em sub tipo repo:minha-org/meu-repo:ref:refs/heads/main. Wildcards são permitidos mas use com cuidado — repo:minha-org/*:* confia em todo workflow da org.
O IRSA (IAM Roles for Service Accounts) é o mesmo padrão para EKS — service accounts do Kubernetes ganham credenciais IAM via o provider OIDC do cluster. Os dois usam sts:AssumeRoleWithWebIdentity.
Pegadinhas comuns
- Esquecer o
ExternalIdem trust de vendor SaaS — abre brecha para confused-deputy. - Confiar em
arn:aws:iam::ACCOUNT:rootsem mais conditions — delega TODA a decisão de identidade para a outra conta. - Wildcards no Principal (
"Principal": "*") tornam o role assumível por qualquer pessoa na internet — só seguro com conditions rígidas. - Service principals são case-sensitive:
Lambda.amazonaws.comnão funciona,lambda.amazonaws.comsim. - Atualizar a trust policy de um role em uso não revoga sessões ativas — credenciais STS de curta duração continuam funcionando até expirar o TTL.
FAQ
Trust policy vs permission policy? Trust diz quem entra no role; permission diz o que ele faz depois de dentro. Todo role tem exatamente uma da primeira e uma ou mais da segunda.
Toda role precisa de trust policy? Sim — sem ela, ninguém assume o role e ele fica inútil. A AWS rejeita a criação do role se você não fornecer uma trust policy.
Posso listar vários Principals? Sim — Principal aceita um único valor ou um array: "Principal": {"Service": ["ec2.amazonaws.com", "lambda.amazonaws.com"]}. Útil para execution roles compartilhados.
Para que serve o ExternalId? Segredo compartilhado entre você e um vendor SaaS, passado na chamada AssumeRole. Impede que um atacante engane o vendor para operar na conta de outro cliente (confused deputy).
Por que GitHub OIDC é melhor que IAM users para CI? Não precisa guardar access keys de longa duração como secret do repo. Credenciais STS de curta duração, geradas por execução, com escopo restrito ao repo/branch via claim sub.
Ferramentas Relacionadas
Gerador de AWS IAM Policy
Gera uma política IAM da AWS (versão 2012-10-17) a partir de Effect, Actions e Resources informados em texto.
Gerador de IAM Policy AWS S3
Gera um documento JSON de policy IAM para AWS S3: read-only, write, full access ou customizado por bucket. Pronto para colar no IAM.
Gerador de comando AWS S3
Monta comandos aws s3 (cp, sync, ls, rm) com bucket, caminho, ACL, recursividade, classe de armazenamento e perfil.