What follows opens on a constructed illustration. It is not an incident, not client work, and not a report of anything that occurred. It is assembled from primitives any platform engineer will recognise from a service they have shipped, because the argument needs a trace concrete enough to check against your own system — and inventing an incident to make a point would be exactly the behaviour this site argues against.

A customer runs an agent on a managed agent runtime. The task is unglamorous: reconcile a supplier catalogue against a pricing table and correct the drift. The agent plans, calls a first-party connector into the customer's system of record, and updates a currency field on 1,400 rows. It completes in under four minutes. Nothing errors, nothing alerts, no rate limit is touched. By every operational measure available to the platform, this is a clean run.

Six weeks later the customer's auditor asks two questions. Not a regulator — an auditor, executing a control the customer wrote for itself. *Which policy permitted that update, and what scope did the agent hold at the moment of the first write?*

The platform team has an unusually good answer to a slightly different question. They can produce the ordered sequence of 1,400 calls. They can produce the connector and its API version, the agent's identity and session, timestamps to the millisecond, the before and after value of every field touched, the latency distribution, the token spend. The record is complete, it is append-only, and its integrity holds. It is, by any reasonable standard, excellent telemetry.

It does not contain the answer. Not because a retention window closed — nothing was deleted. Not because sampling dropped it — this was not a sampled path. The authority under which those writes happened was never a record at any point in its existence. It was a value in a stack frame, computed correctly, consumed correctly, and released when the function returned.

The customer is now reconstructing authority from primitives the platform chose to emit. Everything they can say to that auditor is downstream of a schema decision someone made in a design review, probably years before agents, and almost certainly without the words "authorization decision" appearing in the ticket. That decision is a product decision. It has, as far as I can tell, never been framed as one.

FIGURE 1 · TWO RECORDS OF ONE INSTANT The platform wrote down what happened. It was asked what was permitted. 01 · THE EFFECT RECORD What the platform produced 1,400 update calls, in order The connector and its API version The agent identity and its session Timestamps to the millisecond Before and after, every field Latency, tokens, error rate Complete. Verifiable. Append-only, and it holds. 02 · THE AUTHORITY QUESTION What the auditor asked for Which policy version was in force What scope was held at that instant What evidence the evaluator saw How deep the delegation ran Who granted the delegating principal Whether that grant was still valid Not deleted. Not expired. Never written. Both are true records of the same instant. The runtime only ever emitted one of them. vikramjha.work AI AGENT GOVERNANCE & ASSURANCE

This is not a compliance essay and the argument does not depend on any regulator. The question has more than one origin — audit committees at supervised institutions in the United States, regulated entities in India, enterprise buyers across the Gulf — and the mechanism is identical in an unregulated startup with one diligent security lead. The question is architectural. It is being asked of your customers. Your customers can only answer it with what you emit.

The objection, at full strength

The strongest response to everything above is that it is condescending and, in most cases, wrong. It deserves to be stated properly before it is answered, because the version of it that platform engineers actually hold is considerably better than the strawman.

Observability is a mature discipline with a decade of hard-won engineering behind it. Distributed tracing across asynchronous boundaries is solved. Context propagation through queues, retries and fan-out is solved. The people running these systems have thought harder about cardinality budgets than most organisations have thought about anything, because unbounded cardinality is what turns a telemetry pipeline into a second production system with its own on-call rotation. Observability is a serious line item on these teams rather than an afterthought, and that expenditure is not vanity: it is the reason incidents get resolved in minutes rather than days.

And the record genuinely answers most audit questions. Who deleted the bucket, and when, and from which principal, and whether it was through the console or the API — answerable. What the agent wrote to which row — answerable to the byte, with before and after. What it cost, how long it took, which model version served the turn, how many times it retried — all answerable. A team that has built that is entitled to be irritated by an essay implying their logging is inadequate.

There are two further rebuttals, both serious. The first: the policy is the customer's, it lives in the customer's infrastructure-as-code repository, and git already records its version history. The second: some policy engines return the reasoning in the response, so the caller has it and can log it if the caller cares. On both readings the information exists, the platform has done its part, and this is a customer integration problem.

Take the whole of that as granted. It is true. Here is precisely what it does not answer.

Observability answers "what happened" with extraordinary fidelity. The authority question is not a "what happened" question. It is a question about what was true of the permission system at an instant that has passed. A trace tells you the call was made and returned 200. That the call returned 200 implies the authorization check returned allow. It does not carry the inputs that produced the allow, and those inputs — not an explanation, a tuple of values — are the entire content of the auditor's question.

The git rebuttal fails on a specific mechanism, and the mechanism is worth stating exactly because it is the one that convinces people. What is in the repository is a claim about what the repository held. It is not a claim about what the evaluator had loaded. Policy distribution is asynchronous: bundles propagate, and for as long as propagation is in flight one region is still evaluating against a revision another region has already retired. A rollback leaves the repository and the running evaluator in disagreement by design. A failed fetch leaves an evaluator serving the last good bundle for as long as its cache permits, which is the correct availability behaviour and is exactly the case where the repository lies to you.

You do not have to take my word for the significance of this, because a CNCF-graduated open-source policy engine in broad production use already treats it as significant. Open Policy Agent's decision log events carry a *bundles map whose revision field is documented as the revision of the bundle at the time of evaluation*. That field exists because the repository cannot answer the question. Someone, at some point, worked out that the version of the policy that ran is a different fact from the version of the policy that was committed, and made the running system say so.

The second rebuttal — the caller has the reasoning — is where the argument actually bites, and I will come back to it under a heading of its own, because the moment of discard turns out to be a single line of ordinary application code that nobody experiences as a logging decision.

What a log is, physically

Strip away the tooling and a log is a simple object: an append-only sequence of records of effects. Three properties of that object matter here, and all three are usually treated as obvious, which is why the consequence is missed.

*First, the integrity guarantee is about the sequence, not the records.* Append-only means nobody rewrote entry 4,112 after the fact. It says nothing whatever about whether entry 4,112 contains the field you will need in six weeks. A cryptographically perfect log of the wrong fields is a cryptographically perfect record of your own earlier assumptions. Integrity is orthogonal to sufficiency, and organisations routinely spend on the first while believing they have bought the second.

*Second, what gets written is what the emitter decided to write, at write time, under the emitter's model of what would later be asked.* That model is the schema. A schema is therefore a prediction — a bet placed by its author about the shape of future questions. Every log in production is somebody's forecast of what would matter, frozen at the moment the struct was defined. Agent workloads are a recent production category, and much of the schema they emit into was designed before them.

*Third, and this is the load-bearing one: authority is not an effect.* An effect is a change in the world — a row updated, a message sent, a file written. It has physical consequences and leaves physical residue. An authorization verdict is a predicate over system state at an instant. Evaluating it changes nothing. It writes no row, sends no message, moves no byte outside the evaluating process. If nobody deliberately records it, it leaves no trace at all, because there was no trace to leave.

The consequence is sharper than it first sounds, and it is the sentence I would put on the whiteboard.

An allowed action and an unchecked action produce identical effects. The log cannot distinguish them, because the difference between them existed only inside the evaluator.

A denied action is even starker: it produces no effect at all, so a log of effects contains no evidence that a permission system exists. Two systems — one with a rigorous, well-tested policy layer and one with no authorization at all — emit byte-identical effect logs for every request that succeeds. From the log alone you cannot tell which one you are running. That is not a criticism of anyone's implementation. It is what a log of effects is.

Authority is a function, and these are its arguments

The reason authority resists being recorded as an afterthought is that it is not a value. It is the output of a function with several time-varying arguments, and recording the output without the arguments preserves almost nothing. Write it out:

*authority = f(policy version, principal and scope, request context, delegation depth, evidence at t) → verdict*

Each argument fails to survive the call for its own reason, and the reasons are different enough that no single fix addresses them.

Policy version is not what your repository says. It is the bundle the evaluator had loaded when it decided. Under normal operation those agree. Under the conditions where the question actually gets asked — after a rollback, during a bad deploy, in the region that lagged — they systematically disagree, and they disagree in the direction that matters, because the incident and the propagation failure have a common cause.

Principal is not identity. Agent identity has genuinely improved. Microsoft Entra Agent ID logs agent activity under the base identity type it originates from — blueprint activity as application events, agent identity activity as service principal events, agent user-account activity as user events — and adds an *agentType property with values including agenticApp, agenticAppInstance and agentIDuser, a blueprintId to correlate an instance back to its template, and a new agentSignIn sign-in event type. Graph access is on the /beta endpoint. That is real progress and it answers who with more precision than most estates previously had for humans. It is an identity and operation record. The auditor's question is about scope* — what that well-identified principal was entitled to at that instant — and scope is mutable independently of identity.

Request context, in an agent stack, is not an input. In a conventional service the attributes passed to the policy engine come from the request: a tenant id, a resource path, a source address, all stable and reproducible. In an agent loop they are frequently outputs of an earlier stage — a value extracted from a retrieved document, a field summarised by the model from a prior tool result, a risk score computed mid-turn. The attributes that determined the verdict may not exist anywhere after the turn ends, and may not be reproducible even by rerunning the same task against the same corpus.

Delegation depth is standardised, informational, and severed in transit. This one is the most interesting, because correct security design makes it worse rather than better.

RFC 8693, OAuth 2.0 Token Exchange, has defined a delegation chain format since January 2020: a chain of delegation can be expressed by nesting one *act claim within another. The outermost act claim represents the current actor while nested act claims represent prior actors. The same specification then constrains what may be done with it — the consumer of a token MUST only consider the token's top-level claims and the party identified as the current actor by the act claim. Prior actors identified by any nested act claims are informational only and are not to be considered in access control decisions.* The chain is audit material by design, deliberately excluded from the verdict.

Now put that next to the Model Context Protocol authorization specification, revision 2025-06-18. It requires audience binding: MCP clients *MUST implement Resource Indicators for OAuth 2.0 as defined in RFC 8707, the resource parameter MUST be included in both authorization requests and token requests, and MCP servers MUST validate that access tokens were issued specifically for them as the intended audience. It then states plainly: the MCP server MUST NOT pass through the token it received from the MCP client.* Every one of those requirements is correct. Token passthrough is a genuine and well-understood vulnerability, and forbidding it is the right call.

The correct behaviour severs the chain. If the token does not cross the hop, the delegation relationship does not cross the hop either — not unless something at the boundary deliberately writes down that it happened. The upstream record names one principal; the downstream record names a different one; nothing in either specification requires a correlation identifier that joins them. The MCP authorization specification defines no artefact recording which authority was evaluated for a given tool call. It was not trying to. It is an authorization specification, not an audit specification, and it does its job.

Evidence at t is gone by construction. Where a verdict depended on a value — an account balance, a risk score, a retrieved document, a freshness check — the verdict is only meaningful alongside what that value was. Six weeks later the balance has moved, the score has been recomputed against a newer model, the document has been re-indexed. Reconstructing the input from the current state produces a confident answer that is wrong, which is worse than producing none.

The discard is structural

A reader who agrees with everything so far can still hold that this is a gap somebody will close next quarter. I think that is wrong, and the reason is that at least five independent forces push toward the discard, none of which is a bug, and all of which would have to be addressed deliberately.

*One: the evaluation is on the hot path.* Authorization is called per tool call, and in agentic systems that means per step of a loop that may run hundreds of steps. Latency budgets are single-digit milliseconds. Emitting a durable, ordered, queryable record per evaluation adds a write to the highest-QPS path in the system and amplifies the authorization service's own storage cost by roughly one record per call. Computing, returning and releasing is the correct engineering decision under those constraints. Nobody is being lazy.

*Two: the return type. AWS Verified Permissions' IsAuthorized returns not only the decision — ALLOW or DENY — but determiningPolicies, documented as the list of determining policies used to make the authorization decision, plus an errors* array. The evaluation rationale genuinely exists, in the response payload, at the instant of decision. The API reference documents the response shape; it makes no statement about whether the service persists that response anywhere, and I am not going to assert either way about something the documentation does not address.

The point does not require it. Consider what the caller does with the object. The ordinary integration branches on the decision field, and the moment that branch is taken every other field is unreachable. The rationale was computed, transmitted across the network at some cost, deserialised, and dropped — not by a logging system, not by a retention policy, but by an ordinary conditional that no reviewer has ever flagged as a data-loss event. *The discard happens in application code, at a line nobody experiences as a logging decision.* Ask any engineer to point at where their system throws away audit evidence and they will look at their retention config. They will not look at an if-statement.

*Three: the telemetry convention being written right now has no place to put it. The OpenTelemetry GenAI agent and framework span conventions carry Status: Development* and define attributes covering operation name, provider, agent id, name and version, conversation id, model request parameters, finish reasons and token usage. They define no attribute for authorization, permission, policy, approval or consent. What the emerging cross-vendor agent telemetry convention captures is effects and cost.

Stated precisely, because the status matters in both directions: these conventions are explicitly marked Status: Development and live in a separate GenAI repository. They are not a settled standard and describing them as one would be wrong. That cuts the optimistic way too — the attribute namespace is open right now, which is the only window in which adding an authority family is cheap. Once a dozen vendors ship dashboards against a stable convention, an omission becomes a migration.

*Four: managed runtime observability is scoped, correctly, to operations. Amazon Bedrock AgentCore Observability describes what it provides as real-time visibility into agent operational performance through access to dashboards powered by Amazon CloudWatch and telemetry for key metrics such as session count, latency, duration, token usage, and error rates, emitted in standardized OpenTelemetry (OTEL)-compatible format, and for memory resources it also outputs spans and log data if you enable it*. That is a performance and cost telemetry product. It is well built for what it says it does. It is not an authority record, and it does not claim to be — which is exactly why treating it as the answer to the auditor's question is the customer's mistake to make and the platform's silence to own.

*Five: the identity work solved a different question, convincingly enough to look like this one. The Entra Agent ID schema above is a real advance in a real problem. The risk is that a platform team, having shipped agent identity logging, reasonably concludes that agent auditability is handled. It is handled for who. The gap is under what*.

Five forces, none of them an error, all pointing the same way. That is what structural means. A gap sustained by one oversight gets patched by one engineer noticing. A gap sustained by a latency budget, an API return type, an in-flight convention, a correctly-scoped product boundary and an adjacent solved problem gets patched only by somebody deciding it is a feature.

FIGURE 2 · LIFETIME OF THE AUTHORITY STATE Authority was computed correctly. Then the stack frame returned. IN-PROCESS AUTHORITY STATE LIFETIME: ONE FRAME Everything the evaluator knew at t · policy bundle revision, as loaded · scope attached to the principal at t · request context, as handed in · delegation depth from a human grant · the rules that determined the verdict · digest of the evidence relied upon returned: one boolean no emission path THE APPEND-ONLY EFFECT LOG Everything that crossed the durability boundary · the call, and the resource it touched · the actor identifier · the timestamp · the field-level diff · the outcome and the latency · nothing about why it was allowed Six weeks later, only the lower box exists. The question names the upper one. vikramjha.work AI AGENT GOVERNANCE & ASSURANCE

Four reconstructions, and where each one breaks

When the question arrives, teams try to answer it. There are four strategies available and each fails on a different mechanism. Working through them is what converts "we should log more" into an understanding of why more logging of the same kind does not help.

  1. *Reconstruct from the policy repository.* Read the commit history, find the version in force on the date, replay. Fails on propagation: what the repository held and what the evaluator loaded are different facts, and they diverge exactly under the conditions — rollbacks, partial deploys, cache-serving during a fetch failure — that produce the incidents worth auditing. Open Policy Agent records the bundle revision at evaluation time because the repository is not authoritative about what ran.
  2. *Reconstruct from the principal's current permissions.* Look up what the agent identity is entitled to today, and assert that it held that scope then. Fails on drift, and fails in the most dangerous available way: it returns a confident, well-formatted, plausible answer that is wrong whenever anything changed in six weeks. An auditor accepts it because it has the shape of evidence. This is the failure mode that should worry a platform team most, because it is the one that does not look like a failure.
  3. *Reconstruct from the delegation chain.* Walk back from the acting principal to the human who granted the authority. Fails at the first hop where a token was exchanged rather than forwarded — which, under the MCP authorization rules, is every hop, by mandate. The chain format exists in RFC 8693 and is defined as informational rather than decisional; the correlation identifier that would let two records be joined across the exchange is required by neither specification.
  4. *Reconstruct from the effect diff.* Argue that since we can see exactly what changed, the authority is implied. Fails on arithmetic. Effects underdetermine authority: many distinct policy states permit the identical write. Recovering "some authority existed" from "the write succeeded" is trivially true and answers nothing the auditor asked, because their question distinguishes a narrow reviewed grant from a blanket one, and both produce the same bytes.

The general form is a projection. The effect record is the authority tuple projected onto its observable coordinates. Projections lose information and are not invertible. No improvement in retention, integrity, completeness or query performance changes that — you cannot recover a discarded dimension by storing the surviving ones more carefully. This is the part of the argument that is not an engineering opinion.

Configuration

The discard, and why the projection does not invert

Three small, self-contained TypeScript files. Nothing here is a proposal — the first shows where the information is lost, the second states honestly what an effect log can be asked, and the third demonstrates that two different policy states produce an identical effect. Paste any of them into a TypeScript playground and run it.

A deliberately small model of the hot path. The evaluator computes six things and the caller wants one. The last function is the whole essay: every field of `evaluation` other than the verdict becomes unreachable at the return statement, and no part of the system treats that as a logging decision.

the-discard.ts
export type Principal = { readonly id: string; readonly scopes: readonly string[] };
export type RequestContext = Readonly<Record<string, string | number | boolean>>;

/** Everything the evaluator knows at the instant it decides. */
export type Evaluation = {
  readonly verdict: "ALLOW" | "DENY";
  readonly policyVersion: string;           // the bundle actually loaded, not the repo HEAD
  readonly principal: Principal;            // identity AND the scope attached to it at t
  readonly context: RequestContext;         // the attributes the evaluator was handed
  readonly delegationDepth: number;         // hops between this actor and a human grant
  readonly determining: readonly string[];  // the rules that produced the verdict
  readonly evidenceDigest: string;          // digest of the inputs the verdict relied on
};

const RULES: readonly { id: string; action: string; scope: string }[] = [
  { id: "r-catalogue-write", action: "record.update", scope: "catalogue:write" },
  { id: "r-catalogue-read", action: "record.read", scope: "catalogue:read" },
];

export function evaluate(
  principal: Principal,
  action: string,
  context: RequestContext,
  policyVersion: string,
): Evaluation {
  const determining = RULES
    .filter((rule) => rule.action === action && principal.scopes.includes(rule.scope))
    .map((rule) => rule.id);

  return {
    verdict: determining.length > 0 ? "ALLOW" : "DENY",
    policyVersion,
    principal,
    context,
    delegationDepth: Number(context["delegation_depth"] ?? 0),
    determining,
    evidenceDigest: digestOf({ action, context, policyVersion }),
  };
}

/** A stand-in. A real digest needs canonical serialisation first — RFC 8785. */
function digestOf(value: unknown): string {
  const text = JSON.stringify(value);
  let hash = 0;
  for (let i = 0; i < text.length; i += 1) hash = (hash * 31 + text.charCodeAt(i)) | 0;
  return "digest:" + (hash >>> 0).toString(16);
}

// ── The line this essay is about ────────────────────────────────────────────
// The caller asked for a boolean and got a correct one. Six computed facts go
// out of scope here. Nobody reviewing this function would describe it as
// deleting audit evidence, and that is precisely the problem.
export function authorize(
  principal: Principal,
  action: string,
  context: RequestContext,
  policyVersion: string,
): boolean {
  const evaluation = evaluate(principal, action, context, policyVersion);
  return evaluation.verdict === "ALLOW";
}

The third file is the one worth running in front of a sceptic. It takes about fifteen seconds and it retires the "we have the diff" objection permanently.

What the field already knows

The reflexive dismissal of everything above is that it is a research problem, that signed decision records are academically interesting and operationally unrealistic, and that a platform cannot ship speculative cryptography into a hot path. That dismissal would be fair if the components were speculative. They are not. Every part of an answer already exists as a settled standard or a shipping product — in a different domain, solving a different problem, with the operational characteristics already known.

The decision record with its version is a shipping product. Open Policy Agent's decision log events carry a *decision_idunique identifier generated for each decision for traceability — plus the input provided in the policy query, the result returned to the client, the path, the timestamp, and the bundles map whose revision field is revision of the bundle at the time of evaluation*. The policy version is therefore recordable at the decision point rather than inferable from the effect log. This is not a proposal. It is documented behaviour in a CNCF-graduated open-source policy engine.

Attaching the decision to the audit event has precedent in the substrate. Kubernetes audit events can carry *authorization.k8s.io/decision and authorization.k8s.io/reason* annotations. The auditing documentation references them without fully specifying when they are populated, so this is an existence proof of the pattern rather than a field to depend on. But the pattern is the point: somebody building one of the most widely operated control planes in the industry decided that the decision, not only the effect, belonged on the record.

Deterministic replay of a policy is an established property, not a hope. Cedar — the language behind Verified Permissions — was designed for offline analysability. Its authors report a sound and complete logical encoding, which enables precise policy analysis, and state that they modeled Cedar in the Lean programming language, and used Lean's proof assistant to prove important properties of Cedar's design, including confirming that refactoring a set of policies does not change the authorized permissions. That matters here for a reason easy to miss: a record naming a policy version and a request is not merely readable by a human, it is *checkable by a machine*. An auditor can re-derive the verdict rather than take it on trust.

*Binding a claim to a specific thing is solved by content address. The in-toto attestation framework requires that each element MUST have digest set, and that subject artifacts are matched purely by digest, regardless of content type*. This is the established pattern for making a signed statement about a specific, immutable object, and it transfers directly: the evidence a verdict relied on is identified by what it was, not by a name that can later point at something else.

*Hashing a JSON record reproducibly is a published RFC. RFC 8785, the JSON Canonicalization Scheme, June 2020, exists because cryptographic operations like hashing and signing need the data to be expressed in an invariant format so that the operations are reliably repeatable*. Any content-addressed decision record needs exactly this — deterministic property ordering and constrained serialisation — or two verifiers hash the same decision differently and the whole scheme quietly fails open.

Append-only with external detectability is running in production. RFC 9162, Certificate Transparency 2.0, states the property such a log actually buys: the logs do not themselves prevent misissuance, but they ensure that interested parties (particularly those named in certificates) can detect such misissuance, with the append-only property achieved using Merkle Trees, which can be used to efficiently prove that any particular instance of the log is a superset of any particular previous instance and to efficiently detect various misbehaviors. Sigstore's Rekor is that pattern deployed for signed metadata rather than certificates — an immutable, tamper-resistant ledger of metadata generated within a software project's supply chain, where auditors can monitor the log for consistency, meaning that the log remains append-only and entries are never mutated or removed, with inclusion proofs available from the command line.

*The container for a signed, time-bounded assertion is a W3C Recommendation. The Verifiable Credentials Data Model 2.0 reached Recommendation on 15 May 2025. It defines a verifiable credential as a tamper-evident credential whose authorship can be cryptographically verified, binding issuer, subject, temporal validity through validFrom and validUntil, a credentialStatus*, and a cryptographic proof. Whatever else an authority record is, it is a signed assertion by an issuer about a subject that was valid over an interval, and that object has a standardised serialisation.

Authority that carries its own limits is a decade-old pattern, not a new one. UCAN 1.0.0 specifies capability tokens where authority travels in the token rather than being resolved against a central server: an issuer DID delegates to an audience, each delegation may only attenuate what it received and never expand it, the chain is cryptographically signed across every link, and tokens are identified by CIDv1 content identifiers using SHA-256 — so a third party verifies the chain without contacting the issuer. Macaroons established the pattern a decade earlier, embedding caveats that attenuate and contextually confine when, where, by who, and for what purpose a target service should authorize requests, using nested chained HMACs so a receiving service can verify the confined authority with no central authorization server in the path.

FIGURE 3 · THE PARTS ARE ALREADY STANDARDISED Nothing here needs inventing. It needs emitting. OPEN POLICY AGENT decision_id + bundle revision The policy version, recorded at the moment of evaluation. VERIFIED PERMISSIONS determiningPolicies beside the verdict The rationale exists in the response, at decision time. RFC 8693 nested act claims A delegation chain in a standard format — audit material, by design. KUBERNETES AUDIT authorization decision + reason The decision attached to the event, not just the effect. IN-TOTO ATTESTATION subject digest A claim bound to a thing by content, never by name. RFC 8785 · JCS canonical JSON So two verifiers hash the same record identically. RFC 9162 · REKOR inclusion and consistency proofs Append-only, and provably so — already in production. W3C VC 2.0 issuer, validFrom, proof A signed, time-bounded, checkable assertion. UCAN · MACAROONS attenuating chains Authority that carries its own limits with it. Nine settled mechanisms. None designed for agents. The gap is assembly and emission, not invention.

Nine mechanisms, all settled, most of them operationally boring, none of them designed for agents. What I could not find, in the published specifications of the major platform and model vendors, is an artefact that assembles them: a signed, content-addressed record of the authority evaluated for a specific agent action, emitted by the runtime before the action, and joinable to the effect. I looked and did not find one published. That is a statement about the published record and about the limits of my search — not a claim that no such thing exists anywhere, which is not something I am in a position to know.

The default-off economics are part of the mechanism

There is a further reason to expect this to stay unfixed by default, and it is not technical. The industry has already made — sensibly, and with good reason — a durable decision about which records are free and which are metered, and authority records will inherit the wrong side of it unless somebody argues otherwise.

AWS CloudTrail states it plainly: by default, trails and event data stores do not log data events. Additional charges apply for data events. Management-plane calls are captured; the resource operations an agent actually performs are opt-in and metered.

Google Cloud draws the same line. Admin Activity audit logs are always written; you can't configure, exclude, or disable them, while Data Access audit logs — except for BigQuery Data Access audit logs — are disabled by default because audit logs can be quite large.

Kubernetes goes further: auditing is off entirely unless configured. An audit policy file must be passed via *--audit-policy-file, and if the flag is omitted, no events are logged*. Four levels exist — None, Metadata, Request, RequestResponse — and only the top level records request and response bodies. Audit content is a deployment choice rather than a platform guarantee.

The pattern is coherent and the reasoning is sound. Control-plane events scale with change and are therefore cheap and mandatory. Data-plane events scale with traffic and are therefore expensive and optional. Nobody should want the third of these decisions reversed on a whim.

But authority evaluations scale with tool calls, which is data-plane volume. If an authority record is classified as a data-plane artefact it will inherit the data-plane default, which is off, opt-in and metered. The customers who most need the record are then exactly the customers who discover the toggle after the question has already arrived — six weeks too late, with the evaluations of the intervening period unrecoverable, because a switch turned on today produces no evidence about last month.

There is a counter worth putting on the table, and it needs stating as a hypothesis rather than a result. An authority record is not the same kind of object as a data event. A data event carries request and response bodies of unbounded size. An authority record is dominated by a version identifier, a principal identifier, a small set of rule ids and a digest — highly repetitive across calls and therefore highly compressible, with the digest doing the work that a payload would otherwise do. *The prediction under test is that a canonicalised authority record for a tool call sits within an order of magnitude of the telemetry span already emitted for that same call.* I have not measured it, no vendor has published the comparison, and if it turns out to be false the volume objection is a real objection rather than an inherited assumption. It is a measurable question and it is currently unmeasured.

Where this argument could be wrong

Five ways, stated at the strength I would want them stated at if I disagreed.

  1. *The coverage is thin.* I read the primary documentation for a small number of platforms — one managed agent runtime's observability guide, one identity provider's agent logging schema — and one in-development telemetry convention. That is not a survey of the field, and I have deliberately not written the sentence "no platform emits this" anywhere in this piece, because I have not earned it. If a managed runtime emits a durable authorization record by default and documents it, the teardown is wrong about that platform and I would like to be told.
  2. *The Verified Permissions case is unresolved.* The API reference documents the response shape of IsAuthorized and says nothing about retention. I do not know whether the service persists determiningPolicies, and I have not asserted either way. My argument survives either answer, because the caller's ability to join that rationale to the effect record is the caller's problem in both cases — but if the service does retain it, one of the components is closer to hand than I have implied.
  3. *This might be the customer's job.* The strongest objection to the whole piece: platforms supply primitives, customers assemble them, and a customer who wants an authority record can write one from the policy engine response and their own instrumentation. For the part of the permission model the customer owns, that is entirely true and they should. It is false for the parts inside your address space — the runtime's own bundle revision, the connector's internal scope resolution, the token exchange you perform on their behalf. A customer can instrument everything they can observe and still not close the gap, because the missing arguments were never in their process.
  4. *The question might not persist.* Supervisory attention on agentic systems is currently deferred rather than intensifying: OCC Bulletin 2026-13, the revised interagency model risk management guidance of 17 April 2026 which supersedes SR 11-7 and SR 21-8, places generative and agentic AI expressly outside its scope and states that it does not set forth enforceable standards or prescriptive requirements. Read as a deferral rather than an exemption — every duty attached to the underlying action survived, and only the framework that would have specified controls was withdrawn — but a reader could reasonably forecast that nobody insists for another two years. I would note that the demand in the opening illustration comes from an auditor executing a customer's own control, and enterprise procurement runs on a considerably faster clock than supervision.
  5. *The economics might genuinely not work.* If the volume prediction above is wrong by two orders of magnitude rather than one, default-on is indefensible and the honest recommendation collapses to a documented opt-in, which is a much weaker piece. That is a measurement, it has not been made publicly, and I would change position on a published one.

The clean falsifier, stated so it can be held against me. A managed agent runtime that emits, by default, a durable record per authorization decision, carrying the policy version resolved at evaluation, the scope resolved for the principal, the determining rules, and a correlation identifier that joins to the effect record — with a published schema and a documented retention default. One vendor shipping that would demote this from structural to lagging, and I would rather be wrong that way than right.

The product decision nobody has framed as one

Return to the trace. The platform did nothing wrong. The runtime evaluated authority, correctly, in-process, and returned. The connector performed the writes it was permitted to perform. The log recorded them completely and has not been tampered with. Every component behaved to specification.

And the customer cannot answer the question, because the answer was never an object. It was a value in a frame, in a process, on a host, on a Tuesday.

The asymmetry is the reason this is worth a platform team's attention rather than a customer's. *You are the only party who can emit the missing arguments, and the only party currently not being asked to.* The pressure lands on your customer's security lead, who escalates to their auditor, who writes a finding, which becomes a diligence question in a renewal, which reaches you as a procurement objection two quarters later with none of its structure intact — arriving as "they want more logs" when the actual request was for a different class of record entirely.

Everything a customer can say about authority today is downstream of a schema decision. That schema was a bet about which questions would be asked, placed by someone reasonable, before agents existed as a production category. The bet was correct at the time. It is now being tested against a question it was not written for, and losing is not a defect in the engineering — it is the ordinary fate of a forecast.

What changes is not a feature. It is what the runtime considers an event. Today an event is something that happened in the world. The proposal implied by everything above is that a decision is also something that happened — that the evaluation of authority is a first-class occurrence with a durable, checkable record, rather than an implementation detail of the thing it authorised. That is a change in ontology before it is a change in code, which is why it will not arrive incrementally and why no amount of better logging of the current kind gets there.

I have deliberately not designed it here. What that artefact contains, how it binds to the evidence it was decided on, why canonical serialisation is load-bearing rather than fussy, what a transparency log buys that a database does not, where it sits relative to the hot path, and what it costs — that is a construction argument and it deserves its own piece. It is forthcoming, as *"Permission receipts: making authority a first-class platform primitive."*

This one only had to establish the gap, and the gap is narrow enough to state in a sentence.

Your log is not wrong. It is a complete and faithful answer to a question your customer has stopped asking.