Free plan Signups are open now. The full audytx engine — Terraform and CloudFormation — is live. The Free plan is 100 scans a month and stays free — paid tiers arrive Nov 01, 2026 from $20/month for unlimited repositories. Try it on your own code.
← Notes
Security · July 1, 2026

The IAM privilege escalation hidden behind a stale date

TL;DR: Bishop Fox's iam-vulnerable ships a matched pair of IAM policies differing by one condition operator. fn3 uses a stale DateGreaterThan bound every credential already clears — the escalation is live. fp5 uses DateLessThan on the same date, which no current credential meets — it's dead. audytx reads the condition operator, not just its presence, and gets both right.
The setup

A condition is more than present or absent

A check that reads an IAM Condition block as present-or-absent has to pick one answer for every dangerous grant that carries a condition: either the condition constrains it, or it doesn't. Whichever it picks, it is wrong for one of the two policies below.

The standard test for exactly this is Bishop Fox's iam-vulnerable, a reference corpus of real AWS IAM privilege-escalation paths. Buried in it is a matched pair named for the two ways a check can get it wrong: fn3 (a false negative waiting to happen) and fp5 (a false positive). They're almost identical.

The pair

One operator apart

Both policies grant iam:CreatePolicyVersion on Resource: "*" — a classic escalation (rewrite a policy you're attached to, grant yourself admin). Both add one condition on aws:TokenIssueTime, the moment a temporary credential was issued. They differ by a single operator:

fn3  →  "DateGreaterThan": { "aws:TokenIssueTime": "2020-01-01T00:00:01Z" }
fp5  →  "DateLessThan":    { "aws:TokenIssueTime": "2020-01-01T00:00:01Z" }
fn3 · exploitable

DateGreaterThan → live

"Issued after Jan 1, 2020" is true for every credential in use today. The condition constrains nothing — dead weight, and the escalation is fully open.

fp5 · dead

DateLessThan → noise

"Issued before Jan 1, 2020" is true for no credential today — AWS says temporary credentials "can be configured to last for anywhere from a few minutes to several hours." The grant is unreachable; flagging it is noise.

AWS frames this pattern the same way: their example of DateGreaterThan aws:TokenIssueTime notes the policy "can be updated programmatically every day to ensure that account members use fresh credentials." The date is meant to be refreshed to roughly yesterday. Left stale at 2020, it's a lock with no bolt.
The result

What audytx does with the pair

To resolve the pair, a check has to read the condition itself — the operator, the key, the value — and ask whether it still constrains anything. audytx does, and gets both policies right.

Policy Should audytx
fn3 (DateGreaterThan) flag flags ✓
fp5 (DateLessThan) stay quiet quiet ✓

Checked against the live engine on July 1, 2026. Both outcomes are pinned by tests in the audytx engine.

The idea

What this proves

This is one policy in one benchmark, chosen because it separates a check that reads a condition from one that only counts it. A security tool should understand what a control does before it trusts it — and stay quiet when the control is real.

audytx reads condition operators, not just whether a condition is present. It gets both halves of the fn3/fp5 pair right: the live escalation is flagged and the dead one is not.

Free plan

Start free

audytx reviews AWS Terraform on every pull request — IAM privilege-escalation and cross-resource attack paths, with context-aware false-positive suppression. Read the verdict on your next PR.

Prefer the agent surface? Wire audytx into your coding agent over MCP. For IAM privilege-escalation and role-chain checks, see /iam-security.