The NIST AI RMF Agentic Profile (Cybersecurity & Infrastructure Security Agency, 2026) is the framework your audit committee will increasingly reference when reviewing your AI-agent deployment. Its core idea: not all AI actions are equal, so they shouldn’t be governed the same way. The model defines four tiers (T0/T1/T2/T3) based on action reversibility, and prescribes different control surfaces for each.

This article walks the four tiers with concrete finance-workflow examples and how to map them to your policy.yaml.

The four tiers, plain English

T0 Read-only or propose-only — no state change T1 Reversible by anyone with the right actor identity, below materiality T2 Reversible above materiality OR sensitive-account routing T3 Irreversible — money moved, period closed, journal posted to a closed period

The progression isn’t about how complex the action is. It’s about how expensive it is to undo. Reading a record is free; submitting a payment to a bank is irreversible. The tier maps to that cost, and the cost determines the routing.

T0 — the agent’s home turf

Examples in finance:

  • run_recon_pass — execute the deterministic matching pipeline; produces match proposals but doesn’t commit anything
  • propose_match — suggest a GL↔SL pairing
  • query_audit — read the audit log
  • investigate_exception — load an unmatched entry + curated near-misses
  • list_pending_escalations — list HITL queue
  • generate_close_summary — synthesize a close-cycle report

Routing: always automatic. No HITL, no SoD check, no materiality gate. The LLM runs full speed.

Why this matters: if your AI agent spends most of its time on T0 actions (and on a well-designed close workflow, it should), it can move fast. The framework’s job is to make T0 actually be T0 — no hidden state mutation, no audit-log entries that look like writes, nothing that needs human review.

T1 — reversible with audit evidence

Examples in finance:

  • reject_match — reject a proposed match; entries go back to UNMATCHED
  • flag_exception — mark an entry as EXCEPTION with rationale
  • escalate_match — surface a match to a named approver
  • resolve_escalation — confirm/reject/withdraw an escalation
  • ap_confirm_invoice_coding — RECEIVED → CODED transition for invoice coding

Routing: automatic. But every action writes an audit row with verbatim policy clause text + JSON-pointer source. The action is reversible by anyone with the right actor identity, but reversibility doesn’t mean unaccountability — the audit log still has to be quoteable in a SOC 2 or SOX walkthrough.

Why this matters: T1 is where most “low-risk” agent automation lives. The temptation is to skip audit logging because the cost is low. Resist it. The point of audit logging at T1 isn’t to prevent malicious activity (you’re already trusting reversibility for that); it’s to give your auditor a reproducible trace when they sample 50 random events.

T2 — the audit-committee threshold

Examples in finance:

  • confirm_match — confirm a proposed match (SoD + materiality + sensitive-account checks fire)
  • ap_approve_invoice_for_payment — invoice approval (SoD: actor ≠ PO requestor)
  • ap_propose_payment_run — group APPROVED invoices into a payment run
  • ap_approve_payment_run — approve the payment run (SoD: approver ≠ requestor)

Routing: HITL required. The LLM proposes; a different human actor confirms. SoD enforced server-side — the LLM cannot impersonate a human, no matter what the chat history claims.

Why this matters: T2 is where your audit committee actually pays attention. It’s the “did a human review this $40K match?” question. The right answer isn’t “the LLM did it”; the right answer is “the LLM proposed it; Alice from accounting confirmed it under a different actor identity tied to her OIDC token, and the verbatim policy clause that fired is logged.”

Sensitive-account routing folds into T2 as well: if the action touches cash, legal accruals, or vendor bank-change events, it routes to HITL regardless of materiality. The policy.yaml field is always_human_accounts; the runtime check is server-side.

T3 — the bank-transfer threshold

Examples in finance:

  • ap_submit_payment_run — submit a payment run to bank/ACH (money leaves)
  • close_period — close the accounting period (post-close edits require dual HITL on a closed period)
  • post_to_closed_period — post a journal entry to a previously-closed period

Routing: DUAL HITL. Three different actor identities, three different humans, full SoD chain. requestor ≠ approver ≠ payer. No prompt can override. No exception.

Why this matters: T3 is where the cost of getting it wrong is irreversible. The AP-submit case is the canonical one — once the payment hits the bank, it’s gone; pulling it back requires a wire reversal at best, a fraud claim at worst. Dual HITL is the only defensible answer.

The closegate runtime enforces this: if the same actor tries to play all three roles, the gate denies with SOD_SAME_ACTOR and writes a POLICY_VIOLATION event with the exact policy clause text. Your auditor can sample the dead-letter queue for these and verify they’re being thrown.

Mapping tiers to your policy.yaml

The closegate policy.yaml schema makes the tier model executable:

materiality_threshold_usd: 10000

always_human_accounts:
  - "1000"           # cash
  - "2000-LEGAL"     # legal accruals
  - "VENDOR_BANK"    # vendor bank-change events

no_auto_confirm_match_types:
  - "fuzzy_match"

clauses:
  SOD_SAME_ACTOR:
    text: "An actor that proposed a match cannot confirm the same match. Separation of duties required."
    source: "/clauses/sod_same_actor"
  MATERIALITY_OVER_THRESHOLD:
    text: "Match amount $${amount} exceeds the materiality threshold $${threshold}. Human approval required."
    source: "/clauses/materiality_over_threshold"

entities:
  us-parent:
    overrides:
      materiality_threshold_usd: 10000
  jp-sub:
    overrides:
      materiality_threshold_usd: 1000000  # ¥1M

The clauses section is what gets quoted verbatim in your audit log. Write it carefully — your external auditor will read it.

Why finance specifically

Generic AI-agent frameworks default to a single-tier model: every action either runs or doesn’t. That works for chatbot tool calls; it doesn’t work when the action is “post a journal entry.”

Finance specifically benefits from tier routing because:

  1. Materiality is well-defined. SOX 404 forces you to articulate it; closegate makes it executable.
  2. Sensitive accounts are well-defined. Cash, legal, intercompany clearing — every controller knows the list.
  3. Reversibility is well-defined. A journal can be reversed; a wire transfer can’t.
  4. Audit-committee comfort is the binding constraint. The tier model gives the audit committee a shared mental model.

What this gives you

  • Tier-routed automation. The agent runs full-speed on T0/T1; T2 routes to a human; T3 routes to dual-HITL with full SoD chain.
  • No “should we ask” logic anywhere in your application code. The gate decides; the tier annotation is the routing rule.
  • Auditor-quotable evidence. Every T1+ event carries the verbatim policy clause text. Auditors don’t translate; they cite.
  • Defensible adoption story. The audit committee sees the same model your engineering team sees.