Especialista

Armadilhas de condições multivaloradas

Lição 20 · Módulo 5 — Especialista

Single-valued vs multivalued

Toda chave de contexto tem um tipo de valor, informado na documentação como Value type:

Single-valuedMultivalued
aws:PrincipalOrgIDaws:PrincipalOrgPaths
aws:PrincipalArnaws:TagKeys
aws:PrincipalTag/<key>aws:ResourceOrgPaths
aws:SourceAccountaws:PrincipalServiceNamesList
  • Multivalued: exige ForAnyValue: ou ForAllValues: antes do operador.
  • Single-valued: nunca use set operators. A AWS alerta que isso pode gerar policies permissivas demais.

As duas regras que você precisa decorar

OperadorSignificadoChave ausente
ForAnyValue:pelo menos um valor da request casafalse
ForAllValues:todos os valores da request casamtrue (!)

O ForAllValues com chave ausente é uma "verdade vazia": se não há valores, nenhum deles viola a regra. É matematicamente correto e perigoso em Allow.

Armadilha 1 — ForAllValues em Allow

JSON — permissiva demais
1
2
3
4
5
6
7
8
9
10
{
"Effect": "Allow",
"Action": "ec2:CreateTags",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["environment", "cost-center"]
}
}
}

A intenção era "só pode usar as tags environment e cost-center". Mas se a request não trouxer aws:TagKeys, a condição é verdadeira e o Allow vale. Correção recomendada pela AWS: um Null check.

JSON — corrigida
1
2
3
4
5
6
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["environment", "cost-center"]
},
"Null": { "aws:TagKeys": "false" }
}

Armadilha 2 — ForAnyValue em Deny

JSON — Deny que não dispara
1
2
3
4
5
6
7
8
9
10
{
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"ForAnyValue:StringNotLike": {
"aws:PrincipalOrgPaths": "o-exemplo/r-ab12/ou-ab12-prod/*"
}
}
}

Intenção: negar quem não está na OU de produção. Mas para um principal sem aws:PrincipalOrgPaths (conta fora de qualquer org ou service principal), o ForAnyValue retorna false e o Deny não se aplica. Justamente quem é mais de fora escapa.

Armadilha 3 — set operator em chave single-valued

JSON — errado
1
2
3
"Condition": {
"ForAnyValue:StringEquals": { "aws:PrincipalOrgID": "o-exemplo" }
}

aws:PrincipalOrgID é single-valued. Use StringEquals puro. O IAM Access Analyzer (policy validation) aponta esse erro, então rode a validação no pipeline.

IfExists e Null: as ferramentas de ausência

  • ...IfExists: "se a chave existir, compare; se não existir, considere verdadeiro". Ideal em Deny de perímetro, onde a ausência é tratada por outra condição (ex.: StringNotEqualsIfExists + BoolIfExists PrincipalIsAWSService, lição 19).
  • Null: testa só a existência. "Null": "aws:TagKeys": "false" exige que a chave exista; "true" exige que esteja ausente.
  • Operadores negados sem set operator (StringNotEquals, ArnNotLike…): com chave ausente, retornam true. Isso é ótimo em Deny e perigoso em Allow.

Teste rápido

Allow com ForAllValues:StringEquals em aws:TagKeys, sem Null check. A request não envia tags. Resultado da condição?

Deny com ForAnyValue:StringNotLike em aws:PrincipalOrgPaths. Quem chama é uma role de uma conta que NÃO pertence a nenhuma org. O Deny se aplica?

Qual a forma correta de exigir a org numa key policy com Principal *?

Resumo

Saiba se a chave é single ou multivalued. ForAnyValue com chave ausente dá false; ForAllValues dá true. Use Null e IfExists para decidir conscientemente o que acontece quando a chave não vem, e valide tudo com o IAM Access Analyzer. Você completou a trilha, do zero ao especialista. 🎉

Referências

Terminou esta lição?

Seu progresso fica salvo apenas neste navegador.