Common Gotchas with ForAllValues and ForAnyValue IAM Condition Operators
When using ForAllValues and ForAnyValue IAM condition operators, always verify the condition key is array-typed, pair ForAllValues with a Null:false check to prevent vacuous truth, and add explicit Null denies for ForAnyValue to ensure missing keys trigger denials.
The ForAllValues and ForAnyValue IAM condition operators enable powerful multi-value matching for array-typed context keys like aws:TagKeys or aws:VpceOrgPaths. However, these operators contain strict logical semantics that can unintentionally grant broad access or fail to trigger denials when keys are missing. The Agent Toolkit for AWS (aws/agent-toolkit-for-aws) documents these critical edge cases in skills/core-skills/aws-iam/references/common-pitfalls.md to help you avoid security holes in your IAM policies.
Applying Set Operators to Scalar Keys
The ForAllValues and ForAnyValue prefixes are designed exclusively for array-typed condition keys (ArrayOfString, ArrayOfARN, ArrayOfNumeric). Applying these operators to scalar keys (e.g., String, Bool) results in undefined behavior that may cause the policy engine to misinterpret your intent.
Before using set operators, verify the key type in the service reference's ConditionKeys list. For scalar keys, use standard operators like StringEquals or StringNotLike instead.
Incorrect: Using ForAnyValue on the scalar key dynamodb:EnclosingOperation.
{
"Effect": "Allow",
"Action": "dynamodb:Query",
"Resource": "*",
"Condition": {
"ForAnyValue:StringEquals": { "dynamodb:EnclosingOperation": "Scan" }
}
}
Correct: Use scalar operators for scalar keys.
{
"Effect": "Allow",
"Action": "dynamodb:Query",
"Resource": "*",
"Condition": {
"StringEquals": { "dynamodb:EnclosingOperation": "Scan" }
}
}
ForAnyValue in Deny Statements Without Null Checks
When a context key is missing, ForAnyValue evaluates to FALSE due to the logical definition of "any value satisfies X" being false for empty sets. In a Deny statement, this means the denial never triggers, potentially allowing requests to bypass your intended restrictions.
To prevent this, add a separate Null check to explicitly deny requests that lack the required key.
Incorrect: A deny that fails to block requests when aws:VpceOrgPaths is absent.
{
"Effect": "Deny",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"ForAnyValue:StringNotLike": {
"aws:VpceOrgPaths": "o-abcdefg/r-12345/ou-123456/*"
}
}
}
Correct: Add a separate statement to deny missing keys.
{
"Effect": "Deny",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"ForAnyValue:StringNotLike": {
"aws:VpceOrgPaths": "o-abcdefg/r-12345/ou-123456/*"
}
}
},
{
"Effect": "Deny",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"Null": { "aws:VpceOrgPaths": "true" }
}
}
ForAllValues in Allow Statements and Vacuous Truth
ForAllValues exhibits vacuous truth: when the context key is missing, the condition evaluates to TRUE because "all values satisfy X" is logically true for empty sets. An Allow statement containing only ForAllValues will therefore grant access even when the key is absent, creating a security hole.
According to the aws/agent-toolkit-for-aws source code in skills/core-skills/aws-iam/references/common-pitfalls.md, you must include a Null condition requiring the key's presence before evaluating the ForAllValues check.
Incorrect: Grants permission when aws:TagKeys is not supplied.
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": { "aws:TagKeys": "a" }
}
}
Correct: Require the key to exist using Null:false.
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "*",
"Condition": {
"Null": { "aws:TagKeys": "false" },
"ForAllValues:StringEquals": { "aws:TagKeys": "a" }
}
}
Missing Required Actions for Multi-Operation APIs
Some AWS operations require multiple IAM actions to function correctly. For example, dynamodb:BatchExecuteStatement requires four PartiQL actions (dynamodb:PartiQLDelete, dynamodb:PartiQLInsert, dynamodb:PartiQLSelect, dynamodb:PartiQLUpdate). Omitting any required action leads to runtime failures even if your conditions are correct.
Consult the service authorization reference and add all needed actions to your policy.
{
"Effect": "Allow",
"Action": [
"dynamodb:BatchExecuteStatement",
"dynamodb:PartiQLDelete",
"dynamodb:PartiQLInsert",
"dynamodb:PartiQLSelect",
"dynamodb:PartiQLUpdate"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/MyTable"
}
Summary
- Verify key types before using
ForAllValuesorForAnyValue; these operators only work with array-typed keys (ArrayOfString,ArrayOfARN, etc.) and produce undefined behavior on scalars. - Guard
ForAllValueswithNull:falseto prevent vacuous truth from allowing requests when keys are missing. - Add explicit
Nulldenies when usingForAnyValuein deny statements to ensure missing keys trigger denials rather than evaluating to false. - Include all required actions for multi-operation APIs like DynamoDB's
BatchExecuteStatementto avoid runtime authorization failures. - Reference
skills/core-skills/aws-iam/references/common-pitfalls.mdandskills/core-skills/aws-iam/references/aws-iam-policy-generation.mdin the Agent Toolkit for AWS repository for the complete policy generation checklist.
Frequently Asked Questions
What happens if I use ForAllValues in an Allow statement without a Null check?
The condition evaluates to TRUE when the context key is missing due to vacuous truth. This means your policy will grant access to requests that do not contain the expected key, creating a potential security vulnerability. Always add "Null": {"<key>": "false"} to require the key's presence.
Why does my ForAnyValue deny statement fail to block requests?
When the context key is absent, ForAnyValue evaluates to FALSE, causing the deny condition to never trigger. To block requests that lack the key, you must add a separate deny statement with a Null check (e.g., "Null": {"aws:VpceOrgPaths": "true"}) or combine it with the ForAnyValue condition.
Can I use ForAllValues or ForAnyValue with scalar condition keys like String or Bool?
No. These operators are designed exclusively for array-typed condition keys. Using them on scalar keys (String, Bool, Numeric) results in undefined behavior. Use standard scalar operators like StringEquals or Bool instead, as documented in skills/core-skills/aws-iam/references/common-pitfalls.md.
Where can I find the official documentation for these IAM condition operators?
The Agent Toolkit for AWS repository (aws/agent-toolkit-for-aws) maintains detailed references in skills/core-skills/aws-iam/references/common-pitfalls.md and skills/core-skills/aws-iam/references/aws-iam-policy-generation.md. These files provide the definitive checklist for safe policy creation with ForAllValues and ForAnyValue operators.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →