Network authority family

Authority Revocation Receipt: settling whether an action fell before, inside, or after the revocation window

The Authority Revocation Receipt is a signed statement that a named action, a named revocation, and a precommitted propagation bound satisfy a deterministic temporal classification procedure. The action lands in one of four classes: before the revocation, inside the propagation bound, after that bound, or indeterminate. Every instant carries its own drift, and a definite class is emitted only when the entire declared uncertainty interval stays on one side. Principals who revoke, actors who act, and acceptors caught between them need it.

The property that separates it from a revocation list is that the tolerance was fixed before the revocation happened. Every revocation system has a propagation delay and every argument about a revoked credential turns into an argument about how long that delay was reasonably allowed to be. Here the propagation bound lives in a prior policy receipt whose issuance instant has to be strictly earlier than the earliest possible revocation instant. Nobody gets to choose the tolerance after seeing where the action landed. The authority itself appears only as a commitment.

The problem

A principal revokes authority. An action happens. The two are close together in time. Was the action inside the authority or outside it?

Everyone knows revocation is not instantaneous. A revoked credential propagates through caches, replicas, edge nodes and downstream systems. During that window an acceptor can honestly rely on authority that has already been withdrawn. Every real system has this window, and almost no system writes down how long it is allowed to be.

Name the parties. The principal asserts it revoked at a certain moment and that anything after that moment was unauthorised. The actor asserts it never received the revocation and acted in good faith. The acceptor asserts it checked what it could check. A downstream party who suffered something asserts that somebody should have known.

Three failures make this unresolvable today.

The first is that the tolerance is argued after the fact. If the action landed thirty seconds after the revocation, the principal says propagation should have been immediate and the actor says thirty seconds is nothing. Both positions are constructed with knowledge of where the action landed. There is no artifact that fixed the number in advance.

The second is clock precision. Two instants recorded by two systems, thirty seconds apart, cannot be ordered with confidence unless somebody records how accurate each clock was. Records almost never do, so orderings get asserted at a precision the underlying clocks never supported. That produces confident findings built on nothing.

The third is that notification gets conflated with knowledge. Somebody produces evidence that a revocation notice was sent, or published, and the argument slides from "notice was sent" to "the actor knew". Those are different facts and only the first one is in the evidence.

Confidentiality compounds it. The authority being revoked is often a credential whose existence is itself sensitive. An artifact that settles the timing question by naming the authority cannot be shared with the parties who need the timing question settled.

When the actor is autonomous, the propagation window becomes the dominant term. An agent operating at machine speed can complete thousands of actions inside a revocation window that a human would never have noticed. The question of what happened inside that window stops being a corner case and becomes the main event.

What the receipt binds

The schema is at https://thehiveryiq.com/.well-known/schemas/authority-revocation-v1.json.

FieldMeaning
receipt_typeFixed to authority.revocation.
schemaFixed to r1.0.0.
finding_idIdentifier of up to 256 characters from letters, digits, dot, underscore, colon and hyphen.
authority_refThe authority in question, as an authority_commitment and a reference_class of issuer_resolved, caller_supplied or asserted_without_source.
actionThe action, as an action_id, an authority_commitment, and an instant carrying a UTC value and drift_seconds up to 86400.
revocationThe revocation, as a revocation_id, an authority_commitment, and an instant with its own drift.
propagationThe tolerance, as propagation_bound_seconds up to 2592000, a propagation_bound_commitment, a salt_b64u of 16 to 128 base64url characters, a salt_commitment, and a prior_receipt naming an authority.propagation_policy receipt with its envelope digest and its own issuance instant and drift.
classificationOne of before_revocation, within_propagation_bound, after_propagation_bound or indeterminate.
notification_evidenceThe evidence class, one of direct_notification_evidence, publication_evidence or none, plus an evidence_envelope_sha256 which may be null.
boundaryThe fixed non attestation string.

The reference_class field deserves a note. It records honestly how the authority commitment was obtained, and asserted_without_source is a permitted value. The receipt does not pretend every authority reference is equally well grounded.

What is deliberately not in the signed body

The authority is not named. It appears as authority_commitment, a 64 character lowercase hex value, in three places that must all be identical.

The propagation bound is visible in the clear as an integer, and it is also bound to the authority by a commitment. The construction in src/typed/authority-revocation.js is HMAC-SHA256 keyed by the decoded salt bytes, over the canonical body of an object holding exactly two fields, the authority commitment and the propagation bound seconds, serialised under the shared canonical rule of recursively sorted keys, no whitespace and non ASCII escaped as lowercase \uXXXX. This makes the bound inseparable from the authority it applies to: you cannot take a generous bound committed for one authority and apply it to another.

The salt commitment is a plain SHA-256 over the decoded salt bytes. The salt itself is present in the body as salt_b64u, which is what lets any reader recompute the bound commitment. The salt is per finding, so it does not link findings together.

Linked artifacts appear as digests. The prior propagation policy receipt is committed by canonical envelope digest, and the notification evidence envelope is committed by digest and never carried. The receipt envelope uses the shared Ed25519 construction over the ASCII string hive-receipt <receipt_id> <payload_sha256> <ts>.

The gates

Verification runs in this order and stops at the first failure.

  1. SCHEMA. Validates the envelope against the authority revocation v1 schema. A failure means the artifact is malformed.
  2. ISSUER_KEY_MATCH. Resolves key_id through the trusted resolver. A failure means the signer is not trusted here.
  3. ENVELOPE_SIGNATURE. Runs the envelope crypto over the payload digest, the receipt identifier form and the Ed25519 signature. A failure names the inner gate.
  4. AUTHORITY_REFERENCE_MATCH. Requires authority_ref.authority_commitment, action.authority_commitment and revocation.authority_commitment to be identical. A failure means the action and the revocation are about different authorities.
  5. PROPAGATION_COMMITMENT_MATCH. Recomputes the salt commitment from the decoded salt and requires it to match, then recomputes the propagation bound commitment from the authority commitment, the bound seconds and the salt and requires that to match. A failure means the bound in the clear is not the bound that was committed.
  6. PRIOR_RECEIPT_LINK. Requires a complete authority.propagation_policy envelope to be supplied, requires its identifier to match, requires its declared type to be exactly authority.propagation_policy, and requires its canonical envelope digest to match. A failure means the policy named was not produced, or a different one was.
  7. PRIOR_RECEIPT_POLICY_MATCH. Requires the prior policy's authority commitment, propagation bound seconds, propagation bound commitment and salt commitment to equal the current ones. A failure names the mismatched item and means the policy relied on is not the policy that governs this authority.
  8. PRECOMMITMENT_ORDER. Requires the latest possible prior policy issuance instant to be strictly earlier than the earliest possible revocation instant, using each instant's own drift. A failure names both computed instants and means the tolerance cannot be distinguished from one written after the revocation.
  9. ACTION_AUTHORITY_MATCH. Requires a supplied action record, requires its action_id to match the body, and independently checks the action's authority commitment. A failure means the action described is not the action supplied.
  10. CLOCK_CONSERVATISM. Fails when the recomputed classification is indeterminate while the declared classification is definite. A failure means a confident finding was claimed over timing that does not support one.
  11. CLASSIFICATION_RECOMPUTE. Recomputes the classification and compares. A failure means the stated class is not the class the instants and the bound produce.
  12. NOTIFICATION_EVIDENCE_CANDOUR. Checks the evidence class against the evidence actually supplied. A failure means the class overstates or misdescribes what is there, including a class of none carrying an evidence digest.
  13. BOUNDARY_CONSTANT. Requires the boundary text to equal the constant. A failure means the non attestation was edited.

The classification rule is worth stating precisely, because it is where the instrument earns its keep. First a nominal class is computed from the two UTC values and the bound: action strictly before revocation gives before_revocation, action at or before revocation plus the bound gives within_propagation_bound, and anything later gives after_propagation_bound. Then the nominal class has to survive the drift. For before_revocation, the action instant plus its drift must still be strictly earlier than the revocation instant minus its drift. For within_propagation_bound, the action instant minus its drift must be at or after the revocation instant plus its drift, and the action instant plus its drift must be at or before the revocation instant minus its drift plus the bound. If a nominal class does not survive its own uncertainty, the result is indeterminate.

That is uncertainty resolving against the finding rather than for it. Two clocks that disagree by more than the gap between the events produce no finding at all, which is the correct answer.

The mint path refuses caller supplied values the service must derive: the receipt type, the schema, the boundary, the classification, both authority commitments on the action and revocation objects, the propagation bound commitment, the salt commitment and the notification evidence envelope digest.

The boundary

This receipt attests only that a named action, a named revocation, and a precommitted propagation bound satisfy the stated deterministic temporal classification procedure. It does not establish that the revocation is authorized, delivered, valid, enforceable, or effective as a matter of contract or law. It does not establish that the action is authorized, unauthorized, excused, ratified, wrongful, binding, or ineffective. A class of within_propagation_bound does not excuse the action and does not allocate risk, fault, responsibility, liability, loss, or remedy. Notification evidence records only the stated evidence class and does not establish that an actor receives, reads, understands, or has actual knowledge of revocation. This receipt does not decide any contractual, statutory, regulatory, evidentiary, or legal consequence, and it does not authorize any action, payment, sanction, denial, or remedy.

BOUNDARY_CONSTANT compares that text against the constant.

The sentence about within_propagation_bound not excusing the action is the one that makes the instrument acceptable to a principal. Without it, no principal would ever agree to a propagation bound in advance, because agreeing would look like agreeing to forgive everything inside it. The receipt separates the timing fact from the excuse completely. An action inside the bound is a timing classification. Whether it is excused is a question for the contract, and the parties can write whatever they like about that knowing the classification will be produced honestly either way.

The notification sentence is the second important one. It draws the line between evidence of sending and evidence of knowing, which is a line that gets crossed constantly in practice. A receipt carrying publication_evidence proves a publication artifact was committed. It proves nothing about whether anyone read it, and the receipt says so, so nobody can build a knowledge argument on top of a delivery record.

Both of these make the dispute smaller. The timing question, which is mechanical and used to be litigated at length, is answered with an auditable computation and a tolerance nobody chose after the fact. Everything else stays with the parties, clearly marked.

Adversarial cases

From test/authority-revocation.test.mjs.

An altered action authority fails AUTHORITY_REFERENCE_MATCH. Presenting an action under one authority against a revocation of another is the simplest forgery, and it fails before any timing is computed.

A rewritten bound fails PROPAGATION_COMMITMENT_MATCH. The direct attack is to widen propagation_bound_seconds in the clear so a late action falls inside. The bound is recomputed from the commitment, and the commitment covers the authority as well, so the widened value does not match.

A substituted prior receipt fails PRIOR_RECEIPT_LINK. Pointing at a more generous policy after the fact changes the canonical envelope digest.

A prior policy with another bound fails PRIOR_RECEIPT_POLICY_MATCH. Supplying the right policy envelope but describing a different bound in the body is caught by the field by field comparison.

Equal prior issuance and revocation fail PRECOMMITMENT_ORDER. The ordering is strict. A policy issued at the same instant as the revocation was not issued before it.

Overlapping prior issuance drift fails PRECOMMITMENT_ORDER. This is the important one. A policy that appears to precede the revocation by less than the combined clock uncertainty does not establish precedence, because the latest possible issuance is not strictly earlier than the earliest possible revocation. The tolerance has to be provably older than the event it governs.

A different supplied action fails ACTION_AUTHORITY_MATCH. The action is checked against an independently supplied record rather than taken from the body alone.

Uncertainty against a definite class fails CLOCK_CONSERVATISM, and conservative uncertainty resolves to indeterminate. These two together are the design. Where the clocks do not support a finding, the only permitted answer is that there is no finding, and claiming otherwise fails.

A stated wrong definite class fails CLASSIFICATION_RECOMPUTE. The declared class is never an input.

A class of none with an evidence digest fails NOTIFICATION_EVIDENCE_CANDOUR. Declaring no notification evidence while carrying a digest of some is incoherent, and the gate refuses it rather than picking one of the two claims to believe.

A changed boundary fails BOUNDARY_CONSTANT after the schema invariant is isolated, and an altered payload digest fails PAYLOAD_DIGEST.

Two structural tests confirm the design. The raw authority identifier and the source salt are absent from the envelope, and the minter refuses every caller supplied computed field.

Performance

From hive-verifier-api/benchmarks/results-latest.json, measured at 2026-08-09T22:28:01.099Z at commit e167719f7d815809c6f55c5dde4495edf1c5615f over 200 iterations:

MeasureValue
Mint p502.756 ms
Mint p953.349 ms
Verify p502.013 ms
Verify p952.521 ms
Artifact size2599 bytes

Local harness measurement on one machine and one Node version, recorded on Node v20.20.1, linux/x64, two Intel Xeon cores at 2.90 GHz. It is a reproducible measurement of this code, not a production latency guarantee.

How to run it

This type has no mint route. It is produced as an export by another route and only verified here, so there is nothing to authenticate against. The verify route takes no credentials.

  • Host: https://thehiveryiq.com/v1
  • Verify route: /verify/authority-revocation
curl -sS -X POST https://thehiveryiq.com/v1/verify/authority-revocation -H 'content-type: application/json' -d '{"receipt": <a receipt of this type>}'

Where it sits in the canon

Family: network authority. Category: typed receipt contract.

It depends on an authority.propagation_policy receipt, which is where the tolerance is precommitted, and it verifies that policy rather than trusting the reference. It answers the question that the Mandate Conformance Receipt explicitly disclaims: that receipt evaluates a delegation as supplied and inherits its revocation limitation, and this is the instrument that addresses the limitation.

It sits alongside authority.qualification, which asks whether the granter had authority at all, and delegation.attenuation, which asks whether each link in a chain narrowed. This one asks only when the authority stopped and where an action fell relative to that.

It does not replace a revocation system, a notification process, or any determination about whether an action was authorised. The boundary rules all of that out in the signed bytes.

Status

production_deployed.

References for this instrument
Canon entry
Authority Revocation Receipt in the Hive canon
JSON Schema
https://thehiveryiq.com/.well-known/schemas/authority-revocation-v1.json
Verify route
POST /verify/authority-revocation
Canonical type
authority.revocation
Private by design. Hive does not store your prompts. Every request is already receipted by a one-way SHA-256 fingerprint, not the words. Proof, not surveillance.