Service principals, SLRs e confused deputy
Lição 18 · Módulo 5 — Especialista
Quem está fazendo a chamada?
Quando um serviço da AWS age "por você", a pergunta-chave para escrever policies é: qual principal aparece na request? Existem três formas bem diferentes:
- Service principal: o próprio serviço, como
cloudtrail.amazonaws.comescrevendo num bucket S3 ousns.amazonaws.comchamando uma Lambda. Aparece como"Principal": "Service": "..."em resource policies. - Role assumida pelo serviço: uma role sua com trust policy para o serviço, como a execution role de uma Lambda. A request sai com credenciais da role, como qualquer outra.
- Forward access session (FAS): o serviço usa suas credenciais para
chamar outro serviço em seguida. Exemplo: você chama
s3:GetObjectnum objeto SSE-KMS e o S3 chamakms:Decryptcom a sua identidade. A chaveaws:ViaAWSServicevemtrue.
Service-linked roles (SLRs)
Uma service-linked role é uma role pré-definida, criada e gerenciada pelo serviço:
- Path fixo:
/aws-service-role/<servico>.amazonaws.com/. - Trust policy e permission policy não são editáveis.
- Só o serviço pode assumi-la.
- SCPs e RCPs não restringem SLRs: os guardrails da org não se aplicam a elas.
Consequência prática (lição 17): se a SLR precisa de algo além da policy gerenciada, como uma CMK de outra conta, o caminho é a resource policy do recurso ou um grant, nunca editar a SLR.
O problema do confused deputy
Uma resource policy assim parece segura:
123456
{ "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::meu-bucket-logs/AWSLogs/*"} Mas ela autoriza o CloudTrail de qualquer cliente da AWS. Outra conta pode configurar uma trail apontando para o seu bucket, e o serviço, o "deputy", vai escrever lá com a permissão que você deu. Esse é o confused deputy entre serviços.
A correção: aws:SourceArn e aws:SourceAccount
Quando um service principal age em nome de um recurso, ele inclui no contexto de qual recurso ou conta vem a chamada:
123456789101112
{ "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::meu-bucket-logs/AWSLogs/111111111111/*", "Condition": { "StringEquals": { "aws:SourceAccount": "111111111111", "aws:SourceArn": "arn:aws:cloudtrail:sa-east-1:111111111111:trail/org-trail" } }} aws:SourceArn: o recurso exato (trail, tópico SNS, regra do EventBridge).aws:SourceAccount: a conta dona do recurso de origem.aws:SourceOrgID/aws:SourceOrgPaths: o equivalente no nível da organização, útil para buckets centrais.
Chaves de contexto: quem tem o quê
| Chave | IAM user/role (inclui SLR) | Service principal |
|---|---|---|
aws:PrincipalOrgID / OrgPaths | Sim (se a conta está na org) | Não |
aws:PrincipalIsAWSService | false (inclusive SLR) | true |
aws:PrincipalServiceName | Não | Sim |
aws:SourceArn / SourceAccount | Não | Sim (quando aplicável) |
aws:ViaAWSService | true em FAS | false |
Repare: uma SLR é uma role IAM. Para as chaves de contexto, ela se comporta
como role, não como service principal (aws:PrincipalIsAWSService vem false).
Esta tabela é a base da próxima lição: se você escrever um Deny exigindo
aws:PrincipalOrgID sem considerar service principals, quebra integrações da própria AWS.
Teste rápido
Sua bucket policy permite sns.amazonaws.com a fazer s3:PutObject, sem nenhuma condição. Qual o risco?
Uma SCP nega kms:CreateGrant para toda a OU. A SLR do Auto Scaling naquela conta é afetada?
Resumo
Antes de escrever uma condição, descubra quem é o principal: service principal,
role assumida pelo serviço ou sua própria identidade via FAS. Para service principals, sempre
amarre com aws:SourceArn/aws:SourceAccount. SLRs são imutáveis e
escapam de SCPs e RCPs, então o controle fica na resource policy do recurso.
Referência Well-Architected
Alinhada com Grant least privilege access.
Referências
Terminou esta lição?
Seu progresso fica salvo apenas neste navegador.