Skip to content

Proof Mode

Most scanners run on probability: "this policy looks like it allows privilege escalation." Proof Mode adds a layer of confirmation: before trusting a statically-detected escalation path, cloud-audit asks AWS's own authorization engine whether the principal's policies actually allow the actions the escalation needs.

cloud-audit scan --verify        # cross-check escalation paths with the IAM policy simulator

Why this matters

cloud-audit detects IAM privilege-escalation paths statically (effective-permission resolution across attached, inline, and group policies). Static resolution is fast but can over- or under-report. Proof Mode cross-checks each path against iam:SimulatePrincipalPolicy - a read-only API that evaluates the principal's real policies and returns an allow/deny decision per action.

The industry is moving the same way: most exposure programs "run on probability, not proof" (Qualys, 2026), and commercial tools now sell exploit validation as a paid flagship. In open source for AWS, that confirmation layer has been missing.

What you get

Each escalation path is annotated verified with a verification_detail evidence string:

  • verified: true - the simulator allowed every required action. This confirms the permission exists (policy-allowed). It is not a guarantee the end-to-end attack works.
  • verified: false - the simulator denied a required action. This is the strongest signal: the statically-detected path is very likely a false positive, because the principal doesn't actually have the permission. Proof Mode's biggest practical win is removing paths you'd otherwise chase.
  • verified: null - not asserted (see honest limits below).

Plus a scan summary line:

Proof Mode: 3/11 escalation path(s) policy-allowed by IAM simulator (read-only check, not full exploit confirmation)

For HAIT-style engagements this trims a list of maybes down to the paths whose permissions AWS itself confirms - and flags the ones it denies as likely noise.

Honest framing (read this)

Proof Mode is deliberately precise about what it claims - over-claiming would be worse than not having it:

  • Paths are simulated, not executed. cloud-audit never performs the escalation.
  • A true result confirms the permission, not exploitability. As of the IAM policy simulator update of 2026-07-30 the simulator evaluates identity policies, the permissions boundary attached to the principal and the organization's SCPs (including their condition keys and resource scoping). It does not evaluate resource control policies (RCPs), VPC endpoint policies, role chaining, or resource-based policies for IAM roles, and AWS notes results can still differ from the live environment. When an SCP or the boundary is the reason for a deny, the detail text says so.
  • Resource-scoped methods are intentionally left null. Without resource ARNs the simulator evaluates against *. For iam:PassRole (to a specific role), sts:AssumeRole (to a specific role), or compute-hijack into a specific target, an allowed on * does not prove the specific target is privileged or passable - so Proof Mode does not assert those (it would over-report). Only methods where a broad evaluation is meaningful (IAM self-mutation / credential creation, where "allowed at all" is the escalation) are asserted true/false.
  • Paths gated by unevaluated condition keys (e.g. aws:MultiFactorAuthPresent) are also left null, with the missing keys named in the detail.

Per-resource proof (agent-blast)

cloud-audit agent-blast --verify uses the second Proof Mode entry point: one action against a list of concrete resource ARNs, with ContextEntries carrying the context an attacker holding the credentials has (aws:MultiFactorAuthPresent=false, aws:SecureTransport=true). The simulator returns a decision per resource, and cloud-audit records PROVEN, DENIED (naming the SCP or permissions boundary when the simulator reports it) or not asserted. Wildcard reaches stay unproven because a * simulation cannot name the resource; a bucket-wide grant is proven on a synthetic object key inside the bucket. See agent-blast.

Resource-scoped escalation methods (PassRole to a specific role, AssumeRole to a specific role) still stay null under scan --verify: without knowing the target role, an allowed on * proves nothing about it.

Cost and scope

  • iam:SimulatePrincipalPolicy is a standard IAM API with no per-call charge. Proof Mode is opt-in (--verify) only to control latency / API throttling, not cost.
  • Calls are deduplicated per unique (principal, action-set).
  • A simulator error leaves the affected path null and never fails the scan; one path's error never affects another.

Usage

# Cross-check escalation paths during a normal scan
cloud-audit scan --verify

# JSON output carries verified + verification_detail on each escalation path
cloud-audit scan --verify --format json -o report.json