KMS: key policies e grants cross-account
Lição 17 · Módulo 5 — Especialista
O cenário
Uma conta central de segurança (111111111111) cria uma CMK para criptografar
volumes EBS e a compartilha com as OUs da organização. Na conta de workload
(222222222222), um Auto Scaling group com launch template de EBS criptografado
com essa chave tenta subir instâncias e todas terminam na hora:
123
Client.InvalidKMSKey.InvalidState:One or more of the attached Amazon EBS volumes are encryptedwith an inaccessible AWS KMS key. A key policy "parece certa". Por que não funciona? Para responder, você precisa de três peças: como o KMS autoriza, quem é o principal de fato e o que muda em cross-account.
Três mecanismos de autorização no KMS
No KMS, a key policy é a fonte de verdade. Diferente de outros serviços, sem a key policy permitir (direta ou indiretamente), ninguém usa a chave, nem o root da conta.
- Key policy: resource policy obrigatória da chave. Pode citar principais
diretamente ou delegar para o IAM da conta via
"Principal": "arn:aws:iam::CONTA:root". - IAM policies: só têm efeito se a key policy delegar para a conta dona do principal.
- Grants: autorizações delegadas e temporárias. Um grant dá a um grantee principal um conjunto de operações na chave, sem precisar mexer em key policy nem em IAM policy. É o mecanismo que EBS, RDS e outros serviços usam por baixo.
Same-account vs cross-account no KMS
Lembra da lição 11? Em same-account, a key policy citando o principal pelo ARN basta. Em cross-account, o KMS exige autorização nos dois lados:
- A key policy (conta da chave) precisa permitir o principal ou a conta externa.
- Uma IAM policy na conta externa precisa permitir as ações naquela chave.
Ou, alternativamente, um grant para o principal externo substitui o item 2.
A key policy do cenário
Uma policy comum em ambientes multi-conta, abreviada:
123456789101112131415161718192021222324252627282930313233
{ "Sid": "OrgUsage", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": ["kms:Encrypt","kms:Decrypt","kms:ReEncrypt*", "kms:GenerateDataKey*","kms:DescribeKey","kms:CreateGrant"], "Resource": "*", "Condition": { "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": "o-exemplo/r-ab12/ou-ab12-workloads/*" } }},{ "Sid": "AllowAutoScalingSLR", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::222222222222:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" }, "Action": ["kms:Encrypt","kms:Decrypt","kms:ReEncrypt*", "kms:GenerateDataKey*","kms:DescribeKey"], "Resource": "*"},{ "Sid": "AllowAutoScalingSLRGrants", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::222222222222:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" }, "Action": "kms:CreateGrant", "Resource": "*", "Condition": { "Bool": { "kms:GrantIsForAWSResource": "true" } }}
Do lado da chave, está tudo certo. Note que OrgUsage com Principal: "*" não atrapalha a SLR: Allows se somam. Se a condição não casar, essa statement
simplesmente não se aplica, e as statements específicas da SLR continuam valendo.
Só um Deny explícito bloquearia.
Mesmo assim, falha. O que falta é o lado da conta 222222222222.
A solução: grant criado na conta do ASG
A documentação do EC2 Auto Scaling
é explícita: para CMK de outra conta, uma identidade da conta do ASG (com kms:CreateGrant
permitido pela key policy e pelo IAM local) cria um grant para a SLR:
123456
aws kms create-grant \ --region sa-east-1 \ --key-id arn:aws:kms:sa-east-1:111111111111:key/EXEMPLO-KEY-ID \ --grantee-principal arn:aws:iam::222222222222:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling \ --operations "Encrypt" "Decrypt" "ReEncryptFrom" "ReEncryptTo" \ "GenerateDataKey" "GenerateDataKeyWithoutPlaintext" "DescribeKey" "CreateGrant" - Use o ARN completo da chave, não um alias, porque aliases não resolvem cross-account.
- Rode com credenciais da conta do ASG.
- A SLR precisa existir antes, porque o grant é vinculado ao ID interno da role.
- Prefira IaC (Terraform
aws_kms_grant, CloudFormation custom resource) a um passo manual esquecido.
Checklist de diagnóstico
aws kms describe-key: a chave estáEnablede na região certa?- A AMI ou o snapshot usa outra CMK? A SLR precisa de acesso a ela também.
- CloudTrail da conta da chave: qual operação falhou (
CreateGrant,GenerateDataKeyWithoutPlaintext,DescribeKey) e qualerrorMessage? - Existe Deny na key policy alcançando o principal? SCPs e RCPs não afetam a SLR, mas afetam a role que cria o grant.
- Cross-account? Então confirme o grant:
aws kms list-grants --key-id <arn>.
Teste rápido
A key policy (conta A) cita explicitamente a SLR do Auto Scaling da conta B com todas as ações corretas. O ASG na conta B continua falhando. Qual a causa mais provável?
Mesmo cenário, mas ASG e chave estão na MESMA conta. As duas statements da SLR na key policy bastam?
Resumo
No KMS, a key policy manda. Em cross-account, você precisa dos dois lados, e quando o principal é uma SLR (policy imutável), o grant é o que fecha a conta. Statements Allow com condições de Org não "roubam" a avaliação de outras statements: se algo bloqueia, procure um Deny ou a metade cross-account que faltou.
Referência Well-Architected
Alinhada com Implement secure key management e Share resources securely within your organization.
Referências
Terminou esta lição?
Seu progresso fica salvo apenas neste navegador.