IAM ForAllValues Condition Evaluation Pitfalls and How to Avoid Them

When an IAM policy uses ForAllValues:StringEquals, missing or empty context keys evaluate to true by default, potentially allowing unintended access unless you add a Null condition to enforce key presence.

The aws/agent-toolkit-for-aws repository documents critical security behaviors in AWS IAM policy conditions. Understanding IAM ForAllValues condition evaluation is essential because the default behavior for missing keys can silently bypass your intended restrictions. This guide explains the vacuous truth problem and the specific guard clause required to fix it, based on the official IAM skill documentation.

Understanding the Vacuous Truth Problem

When you use a ForAllValues condition operator like ForAllValues:StringEquals, the policy engine checks that every element in the request context matches your specified values. However, if the context key referenced in the condition is absent or empty, the condition evaluates to true—a logical case known as vacuous truth.

According to the source documentation in skills/core-skills/aws-iam/SKILL.md (lines 53-68), this behavior means that requests omitting the context key entirely may pass your security controls unintentionally. The same warning appears in the plugin version at plugins/aws-core/skills/aws-iam/SKILL.md (lines 53-68).

The Mandatory Null Condition Guard

To prevent vacuous truth from bypassing your restrictions, you must add a Null condition on the same context key, explicitly requiring the key to be present and non-null. Set the Null condition value to "false" to force the policy engine to reject requests where the key is missing.

This combination ensures that:

  • The ForAllValues logic applies only when the key actually exists
  • Requests without the context key are explicitly denied
  • Empty lists fail the Null check (since "false" requires a non-null value)

Practical Implementation Examples

The Risky Policy (Vacuous Truth Exposure)

The following policy allows ec2:RunInstances only if all tag keys are either "Alpha" or "Beta". However, if the request omits aws:TagKeys entirely, the condition vacuously evaluates to true and allows the action:

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ForAllValues:StringEquals": {
        "aws:TagKeys": ["Alpha", "Beta"]
      }
    }
  }
}

The Secured Policy (With Null Guard)

Adding the Null condition forces the request to include aws:TagKeys with at least one value. If the key is missing or null, the Null condition fails and denies access:

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ForAllValues:StringEquals": {
        "aws:TagKeys": ["Alpha", "Beta"]
      },
      "Null": {
        "aws:TagKeys": "false"
      }
    }
  }
}

Syntax Breakdown

The "Null": {"aws:TagKeys": "false"} construct tells IAM that the key must not be null. When combined with ForAllValues, this creates a two-layer validation:

  1. Presence check: The Null condition confirms the key exists and contains values
  2. Value check: The ForAllValues condition validates that every provided value matches your allowed list

Source Code Reference

This guidance originates from the AWS agent toolkit's IAM skill documentation:

Both files provide the JSON examples and detailed explanations that form the basis of this security best practice.

Summary

  • ForAllValues evaluates to true when the context key is missing or empty due to vacuous truth logic
  • Always pair ForAllValues with a Null condition set to "false" on the same key to enforce presence
  • Validate tag-based policies carefully, as aws:TagKeys is frequently omitted in API requests
  • Reference the source files at skills/core-skills/aws-iam/SKILL.md for the complete implementation guidance

Frequently Asked Questions

What happens if aws:TagKeys is missing in a ForAllValues condition?

The condition evaluates to true, potentially allowing unintended access. When the context key is absent, the "for all values" statement is vacuously satisfied because there are no values to compare against your restrictions.

Why does ForAllValues return true for empty sets?

This follows the logical principle of vacuous truth. In IAM policy evaluation, asserting that "all values match X" is considered true when there are zero values to check, similar to how "all unicorns are blue" is logically true if no unicorns exist.

How do I force IAM to check for key presence?

Add a Null condition with a value of "false" on the same context key. This explicitly requires the key to be present and non-null, preventing the vacuous truth scenario from bypassing your security controls.

Where is this documented in the AWS agent toolkit?

The documentation appears in skills/core-skills/aws-iam/SKILL.md at lines 53-68, with identical content mirrored in plugins/aws-core/skills/aws-iam/SKILL.md at lines 53-68. These files contain the authoritative JSON examples and explanations for implementing safe ForAllValues conditions.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →