Skip to main content

Docs

Execution grants

The grant carries authority. It does not prove that authority was consumed.

A decision says what may happen. A grant says what authority was issued for one operation, against one target, for a bounded time. It is the permission object, and it is a separate thing from the evidence that something happened.

The eight fields that carry the model

what is authorized

operationtarget_uri

against which context

executor_idadapter_idtenant_id

under which constraints

expected_state_tokennonce_hash

until when

expires_at

Together, these say what operation is authorized, against which target and execution context, under which freshness and replay constraints, and until when.

What the grant proves

Everything in this section follows mechanically from the seventeen signed fields. A verifier with the right key and no network can establish all of it.

What makes it usable

Only what ships. Verification against a pinned keyring is offline and needs no CodeRifts call. Expiry and not_before are read from the signed body. Scope binding — executor, adapter, target, operation — is a byte comparison against the presented context.

The implicit default grant version is dated: a caller that omits grant_version is served by that default, and the date it changes is in the code. This page describes the mechanism, not today's answer — whether the default you receive is cr.exec.v1 or cr.exec.v2 is not something this page can tell you.

What makes it single-use

nonce_hash

The grant carries a nonce for single-use enforcement.

not by itself

Single-use is a property of the consuming enforcement path, not of the signed grant.

The signed grant does not make itself single-use. It carries nonce_hash. Single-use requires a consuming enforcement mechanism that rejects reuse.

The shipped guard does not attest nonce consumption. Where its result classifies nonceConsumedOnce, that value is supplied by the host. Reading the guard result therefore means reading the host's assertion about consumption, not a CodeRifts observation of consumption.

Measured 2026-09-17: consumeOnce appears in the adapter layer of the capability demo and in the conformance package. It does not appear in the shipped guard's source. The commit observation the guard emits is reported, and it does not turn any decision into a refusal.

What it does not prove

Full grant fields

Seventeen fields, plus one that appears only when the caller supplies it. Measured from the shipped issuer on 2026-09-17.

fieldtype requiredmeaning
vstringrequiredThe grant format. cr.exec.v2 today when the caller asks for it by name.
kidstringrequiredWhich signing key produced the signature. A verifier resolves it against a pinned keyring.
grant_idstringrequiredA UUID minted per grant. The attestation binds this id.
receipt_hashstringrequiredsha256 of the decision receipt this grant was issued against.
tenant_idstringrequiredWhose grant it is.
executor_idstringrequiredWhich executor may present it. A different executor does not match.
adapter_idstringrequiredWhich adapter may spend it.
operationstringrequiredThe operation authorized — not a class of operations.
target_uristringrequiredThe canonical target. The scheme set is closed: fs, git, api, db, registry, deploy.
expected_state_tokenstringrequiredThe state the target must be in before the change. Defaults to sha256: of the empty string when the caller supplies none.
after_payload_hashstringrequiredsha256 of the intended after-payload. A different payload does not match.
nonce_hashstringrequiredsha256 of the nonce. The hash, not the nonce. See the single-use section below.
policy_hashstringrequiredWhich policy was in force. Normalised to sha256: form.
audience_hashstringrequiredsha256 of the intended audience.
not_beforeintegerrequiredUTC seconds. Earlier than this, the grant is not yet valid.
expires_atintegerrequiredUTC seconds. After this, the grant is expired.
max_attemptsintegerrequiredHow many attempts the grant admits.
environmentstringpresent only when suppliedStaging and production grants were byte-identical without it. Omitted when absent, never defaulted to a string — writing an empty value would change the signature of every grant that never asked for the field.

Two names that are easy to get wrong