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-valued | Multivalued |
|---|---|
aws:PrincipalOrgID | aws:PrincipalOrgPaths |
aws:PrincipalArn | aws:TagKeys |
aws:PrincipalTag/<key> | aws:ResourceOrgPaths |
aws:SourceAccount | aws:PrincipalServiceNamesList |
- Multivalued: exige
ForAnyValue:ouForAllValues: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
| Operador | Significado | Chave ausente |
|---|---|---|
ForAnyValue: | pelo menos um valor da request casa | false |
ForAllValues: | todos os valores da request casam | true (!) |
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
12345678910
{ "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.
123456
"Condition": { "ForAllValues:StringEquals": { "aws:TagKeys": ["environment", "cost-center"] }, "Null": { "aws:TagKeys": "false" }} Armadilha 2 — ForAnyValue em Deny
12345678910
{ "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
123
"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.