# Common Gotchas with ForAllValues and ForAnyValue IAM Condition Operators

> Master ForAllValues and ForAnyValue IAM condition operators. Learn common gotchas like array-type checks, preventing vacuous truth with Null:false, and explicit Null denies.

- Repository: [Amazon Web Services/agent-toolkit-for-aws](https://github.com/aws/agent-toolkit-for-aws)
- Tags: best-practices
- Published: 2026-07-03

---

**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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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`.

```json
{
  "Effect": "Allow",
  "Action": "dynamodb:Query",
  "Resource": "*",
  "Condition": {
    "ForAnyValue:StringEquals": { "dynamodb:EnclosingOperation": "Scan" }
  }
}

```

**Correct:** Use scalar operators for scalar keys.

```json
{
  "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.

```json
{
  "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.

```json
{
  "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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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.

```json
{
  "Effect": "Allow",
  "Action": "s3:PutObject",
  "Resource": "*",
  "Condition": {
    "ForAllValues:StringEquals": { "aws:TagKeys": "a" }
  }
}

```

**Correct:** Require the key to exist using `Null:false`.

```json
{
  "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.

```json
{
  "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 `ForAllValues` or `ForAnyValue`; these operators only work with array-typed keys (`ArrayOfString`, `ArrayOfARN`, etc.) and produce undefined behavior on scalars.
- **Guard `ForAllValues` with `Null:false`** to prevent vacuous truth from allowing requests when keys are missing.
- **Add explicit `Null` denies** when using `ForAnyValue` in deny statements to ensure missing keys trigger denials rather than evaluating to false.
- **Include all required actions** for multi-operation APIs like DynamoDB's `BatchExecuteStatement` to avoid runtime authorization failures.
- Reference [`skills/core-skills/aws-iam/references/common-pitfalls.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-iam/references/common-pitfalls.md) and [`skills/core-skills/aws-iam/references/aws-iam-policy-generation.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-iam/references/aws-iam-policy-generation.md) in 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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-iam/references/common-pitfalls.md) and [`skills/core-skills/aws-iam/references/aws-iam-policy-generation.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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.