Governance

Deterministic Authorization for AI Agents

There is a temptation, when building authorization for AI agents, to use an AI to make the decisions. "We'll have a second model judge whether this action should run." The design has intuitive appeal - the judging model can reason over context, handle edge cases, weigh tradeoffs. It is also structurally wrong for authorization. The defect is not in any specific judging model; it is in the class. Authorization needs a property that judging models do not provide and cannot provide: determinism.

Key concepts

Deterministic authorization means that given the same request inputs and the same policy version, the decision is the same, every time, forever. Different inputs may produce different outcomes. Different policy versions may produce different outcomes. But the same request against the same policy is bit-for-bit reproducible. That property is what makes the decision defensible in audit, reproducible during incident review, and comparable across services.

This post explains why determinism is the right design property, what it costs and does not cost to have, how the deterministic contract is expressed, and what the failure modes of non-deterministic approaches look like in production. For the conceptual foundation see deterministic authorization and runtime authorization for AI agents.

Determinism as a property, not a technique

Determinism is cheaper to design for than to retrofit. A deterministic authorization decision has five observable properties:

A decision that does not have all five is not deterministic. A decision that does is usually produced by a small class of systems: rules engines, SMT-based checkers, typed policy languages (Cedar, Rego-as-used-in-admission-control), and hand-written pure functions. The common thread is that they are computations, not inferences.

Why AI agents specifically need this property

AI agents are decision-dense. A single agent workflow can emit hundreds of tool calls. Each call is a request the authorization layer must evaluate. At that volume, three properties matter simultaneously:

A deterministic policy satisfies all three naturally. An LLM-as-judge approach fails at least two of them structurally, regardless of which model is used.

The deterministic contract, concretely

A deterministic authorization contract fits on one page. The request has a fixed shape:

{
  "actor":   { "id": "agent-sales-42", "type": "agent" },
  "surface": "crm.records.update",
  "action":  "write",
  "target":  { "record_id": "cust-10923" },
  "context": {
    "request_id":      "req-9c0e...",
    "idempotency_key": "idem-77f2...",
    "policy_version":  "v47",
    "intended_value":  { "status": "qualified" }
  }
}

The response has a fixed shape:

{
  "outcome":        "permit",
  "policy_version": "v47",
  "rule":           "crm.write.self_service_update",
  "reasons":        ["actor_in_approved_set", "surface_in_scope"],
  "receipt": {
    "hash":      "sha256:ab91...",
    "signature": "MEUCIQC...",
    "issued_at": "2026-04-18T12:04:19Z"
  }
}

The evaluator is a pure function from request to response. The only source of non-determinism that any well-designed system permits is the issued_at timestamp on the receipt envelope - and the receipt's content hash does not cover that field. The core decision - outcome, policy version, rule, reasons - is reproducible from the request and the archived policy.

The failure modes of non-deterministic authorization

The most common mistake is to assume the only non-deterministic approach is "an LLM decides." It is the most obvious one, but several others exist and each fails the contract:

LLM-as-judge

A model evaluates a natural-language description of the proposed action against a natural-language policy and returns allow or deny. The design appeals to teams coming from a research culture: it is flexible, handles edge cases, can reason over context. In production it is an audit disaster.

Why it fails. Same inputs produce different outputs across model versions, across temperatures, across prompt tweaks. The "reason" is a generated string that sometimes reflects the actual internal computation and sometimes does not. There is no stable rule identifier. Two evaluations a week apart on the same request may disagree. None of the five properties of determinism are satisfied.

Heuristic scoring

The gate computes a risk score from multiple signals and compares it to a threshold. The scoring function is floating-point arithmetic with signals that may be sampled (e.g. a model output). The threshold is hand-tuned.

Why it fails. Floating-point arithmetic across platforms is not reproducible to the bit. Sampled signals are not reproducible by definition. Tuned thresholds drift. Replay is approximate at best. Audit ends up with "the score was around 0.74" instead of "rule X fired against input Y."

Feature flags driving outcomes

The gate is deterministic, but a feature flag on the path flips the outcome for certain cohorts. The flag state is not in the request or the receipt.

Why it fails. Replay loses fidelity because the flag state at decision time is not recorded. The request replayed against the archived policy returns a different outcome than the live system did. Determinism requires that everything affecting the outcome be in the inputs or the policy.

Probabilistic approval

The gate samples a Bernoulli variable with probability 1 − p of denial, for some small p. "Mostly permit, rarely deny." Proposals like this do exist and they are bad.

Why it fails. Reproducibility requires that the random seed be part of the input and the seed be archived. That defeats the point of being probabilistic. More importantly, auditors and regulators do not accept stochastic controls for irreversible actions.

What determinism does not cost you

Two objections come up when teams first encounter this principle. Both have clean answers.

"Deterministic policies are rigid."

They are not. Determinism is a property of how the evaluator processes inputs, not a constraint on how rich the policy is. A deterministic Rego policy can consider dozens of signals and express nuanced logic. Context sets can be rich. Lookups can be extensive. The computation is still a pure function of inputs.

What determinism does rule out is the sentence "the policy decides based on vibes." That is a desirable property of a control. Vibes do not belong in authorization; they belong in product design.

"We need the model's judgment for edge cases."

You do not, at the authorization layer. The model can still contribute - but its contribution is a signal that flows into the request, not a decision that flows out of the evaluator. If a model produces a risk score, fine; make the score an input, and have a deterministic policy that compares it to a threshold. The decision remains deterministic, based on a structured input that includes a model-derived signal. If the score is unreproducible, log it as part of the request so that at least the input to the decision is captured.

This is the same discipline that financial institutions have applied to model risk for decades. Models produce signals. Policies consume signals. Decisions are deterministic given the signals. See why SR 11-7 isn't enough for generative AI for the bridge from model risk to execution governance in that regulated context.

Replay: the practical test of determinism

The easiest way to know whether a system is deterministic is to try to replay a decision.

The workflow is: pick a receipt from a month ago. Extract the request. Extract the policy version. Load the archived policy bundle at that version. Evaluate. Compare the outcome and rule to what is on the receipt. If they match, the system is deterministic along that dimension.

Running this test quarterly, against a random sample of receipts, is the single highest-leverage audit practice for an AI authorization system. It catches:

The test is cheap. A single-digit number of engineer hours per quarter. The value is the peace of mind that the decisions the system issued are actually defensible.

What the receipt must contain

Determinism is only useful if the evidence is complete. The receipt has to contain enough to reproduce the decision. That means:

What the receipt does not need to contain:

The discipline is: the receipt plus the archived policy bundle plus the receipt verifier is sufficient to reproduce the decision. Nothing else is required.

Determinism across versions

One subtle case: what happens when policy versions change? The answer is straightforward if the contract is clean. Every receipt carries the version it was evaluated against. Replaying a receipt from last month reconstructs the decision using the policy that was live last month, not the one that is live now. The archive is a time machine, not a view of "what would happen if we decided today."

That property is also what lets you ship policy updates safely. A policy change is a new version. Old receipts are pinned to the old version. New requests go against the new version. There is no retroactive change to decisions already made.

Frequently asked questions

Can we use a deterministic rules engine and still update policies?

Yes. Policy changes are new versions. The engine is still a pure function; only the input data (the policy bundle) has changed. Every version is deterministic in isolation, and replays reconstruct the version active at decision time.

Is this the same as "policy-as-code"?

Policy-as-code is the engineering practice. Deterministic authorization is the runtime property. They are complementary: policy-as-code makes it possible to version, review, and archive policies; deterministic authorization makes the runtime behavior of those policies defensible.

Do we lose anything by not using an LLM judge?

Yes, and intentionally: you lose flexibility to handle cases you did not anticipate. That loss is the entire point. Authorization should not handle cases the designers did not anticipate by making up a decision; it should return SILENCE and force the case to be made explicit through policy or break-glass. The design is conservative on purpose.

Next step

For the category page see deterministic authorization. For the broader runtime model see runtime authorization for AI agents and pre-execution authorization. For the receipt and verification contract see verify.

Next step

Audit your authorization decisions for reproducibility against the archived policy versions that issued them.

Request a demo Review architecture Read protocol Documentation