Especialista

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.com escrevendo num bucket S3 ou sns.amazonaws.com chamando 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:GetObject num objeto SSE-KMS e o S3 chama kms:Decrypt com a sua identidade. A chave aws:ViaAWSService vem true.

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:

JSON — bucket policy (insegura)
1
2
3
4
5
6
{
"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:

JSON — bucket policy (segura)
1
2
3
4
5
6
7
8
9
10
11
12
{
"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ê

ChaveIAM user/role (inclui SLR)Service principal
aws:PrincipalOrgID / OrgPathsSim (se a conta está na org)Não
aws:PrincipalIsAWSServicefalse (inclusive SLR)true
aws:PrincipalServiceNameNãoSim
aws:SourceArn / SourceAccountNãoSim (quando aplicável)
aws:ViaAWSServicetrue em FASfalse

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.