Release candidate. This describes v0.3-rc1, the current release candidate. New and existing relying parties are on it (profile
delegus-). It is not frozen: the commitment construction is awaiting an external cryptography review, and the v0.2 specification stays the normative text until v0.3 is frozen. Details can still change.base- v3
Published at /profiles/delegus-base-v3. Until v0.3 is frozen, the document changes with each release-candidate edit and its hash moves with it; every receipt pins the exact bytes it was decided under, and the hash is fixed at the freeze.
What v3 adds#
New relying parties start on v3. A relying party registered earlier stays on delegus-, unchanged, until it moves.
- Budgets. A Grant can cap total spend, spend per period, or the number of uses. Check P21 asks whether the action fits; the spend itself is the last step, trust check T7, so a refusal never spends. See Budgets.
- Dependencies. An action can declare which earlier decisions it rests on, in
relies_on, and the relying party can state which ones it requires, inrequires. Checks D1–D7 test them. Each entry has a mode:PRIOR_(the earlier decision was genuine and an ALLOW) orDECISION CURRENT_(and the Grant behind it is still in force now).AUTHORITY - Seller-side actions. Three new action types:
commerce:,quote commerce:andaccept commerce:.fulfil - Receipt v2 (
delegus-). The receipt pins the matched authority by a commitment instead of carrying it in plain text; the plain text comes back beside the receipt, to the relying party only. On an ALLOW it also carries a transaction handle that lets the relying party link its own receipts in one transaction.receipt- v2 - Standing. Under
delegus-, T1 also asks whether the company is in good standing (see below).trust- v3
Words used on this page:
- Grant: the signed grant of authority a company (the Principal) gives its agent. Each entry in it is a Capability: an action type with its limits.
- Proof (in plain words, the proof of grant): the agent's short-lived signature over one request, showing it holds the Grant for this exact action.
- Action: what the relying party says the agent is trying to do.
- Relying party: the business that receives the request and asks Delegus Check to verify it.
Protocol checks#
Each check is true, false or "skipped". Protocol checks are designed to be reproducible by anyone given the Grant, Proof, Action, relying-party DID, a clock, the issuer's DID document snapshot, the status-list credential snapshot and, for budgeted Capabilities, the consumption snapshot. D2–D7 are reproducible by a party entitled to the dependency disclosure package; D5 is Delegus's attestation.
| # | Check | DENY reason |
|---|---|---|
| P1 | Grant parses and conforms to §3 (incl. parentGrant absent; budget well-typed) | GRANT_MALFORMED / UNSUPPORTED_FEATURE |
| P2 | kid names a verification method present in the DID document snapshot | ISSUER_KEY_NOT_FOUND |
| P3 | Grant signature verifies | GRANT_SIGNATURE_INVALID |
| P4 | now ≥ validFrom | GRANT_NOT_YET_VALID |
| P5 | now < validUntil | GRANT_EXPIRED |
| P6 | Status credential signed by Delegus Check; bit at statusListIndex is 0 | AUTHORITY_REVOKED |
| P7 | audience, if present, contains RP | AUDIENCE_MISMATCH |
| P8 | Proof parses and conforms to §4 (incl. jti format) | PROOF_MALFORMED |
| P9 | Proof signature verifies against Agent key | PROOF_SIGNATURE_INVALID |
| P10 | Proof iss == Grant sub | PROOF_AGENT_MISMATCH |
| P11 | Proof grant == Grant id | PROOF_GRANT_MISMATCH |
| P12 | Proof aud == RP DID | PROOF_AUDIENCE_MISMATCH |
| P13 | iat within window | PROOF_EXPIRED |
| P14 | action_hash == hash of submitted Action | PROOF_ACTION_MISMATCH |
| P15 | Action valid for its type, including relies_on (1–8 entries, each exactly fingerprint and mode, no repeats); no unknown member | ACTION_MALFORMED |
| P16 | Some Capability matches action.type | ACTION_NOT_AUTHORIZED |
| P17 | All constraint keys known | UNKNOWN_CONSTRAINT |
| P18 | Currency authorized | CURRENCY_NOT_AUTHORIZED |
| P19 | amount ≤ maxAmount | AMOUNT_EXCEEDS_AUTHORITY |
| P20 | resource matches a pattern | RESOURCE_NOT_AUTHORIZED |
| P21 | Some P20 survivor has budget headroom for the action (or declares no budget); period from validFrom in UTC, counts from the snapshot | AUTHORITY_EXHAUSTED |
| D1 | Every requires entry appears in action.relies_on with the same fingerprint and the same mode | DEPENDENCY_NOT_DECLARED |
| D2 | The fingerprint resolves, inside Delegus, to a receipt Delegus Check issued (recomputed from that receipt's bytes and its stored opening) | DEPENDENCY_COMMITMENT_MISMATCH |
| D3 | That receipt's signature verifies against a Delegus Check receipt key and its body equals its payload | DEPENDENCY_RECEIPT_INVALID |
| D4 | Its decision is ALLOW | DEPENDENCY_NOT_ALLOW |
| D5 | Every declared dependency belongs to one internal transaction | DEPENDENCY_TRANSACTION_MISMATCH |
| D6 | CURRENT_AUTHORITY only: now < the dependency receipt's expires_at | DEPENDENCY_AUTHORITY_EXPIRED |
| D7 | CURRENT_AUTHORITY only, three things about the earlier Grant, in this order: its Principal is in good standing (as T1 asks of the action's own Principal); the key that signed it is not marked compromised (as T3); and its revocation bit is 0 in its Principal's status-list credential (as P6). All read in the step before P6. | DEPENDENCY_ISSUER_NOT_TRUSTED / DEPENDENCY_ISSUER_KEY_COMPROMISED / DEPENDENCY_AUTHORITY_REVOKED |
P1–P20 are the v1 checks, with P15 applying the v0.3 Action rules and P16–P20 the v0.3 action types. In plain words, the new ones:
- P21, budget headroom. If the matching Capability has a budget, does this action fit in what is left? When several Capabilities match, the first in Grant order with headroom, or with no budget, is the one used. If Delegus cannot read the counts for a budgeted Capability, P21 fails with
SERVICE_.UNAVAILABLE - D1, required dependencies declared. Everything the relying party requires, the agent's action declares, with the same mode. Only the agent declares; the relying party can require but cannot add to the agent's signed action.
- D2, the earlier decision exists. The fingerprint the action names opens to a receipt Delegus Check issued. A fingerprint names a receipt without revealing which one.
- D3, it is genuine. That receipt's Delegus Check signature is valid.
- D4, it was an ALLOW.
- D5, same transaction. All the declared earlier decisions belong to one transaction.
- D6 and D7, still in force (
CURRENT_only). The Grant behind the earlier decision has not expired (D6) or been revoked (D7) since. ForAUTHORITY PRIOR_, D6 and D7 areDECISION "skipped".
D1 runs once; D2–D7 run for each declared entry, in the order the action lists them. Each Dn is false if any entry fails it. An action with no relies_on, for a relying party that sends no requires, has D1–D7 true.
Trust checks: delegus-trust-v3 #
Trust checks are Delegus's own attestation about the service state (who is registered, key status, replay, budgets). They are not reproducible offline by design.
| # | Check | DENY reason |
|---|---|---|
| T1 | issuer is a registered Principal in good standing | ISSUER_UNKNOWN (not registered) / ISSUER_NOT_TRUSTED (suspended or disputed) |
| T2 | Principal is domain-verified | ISSUER_UNVERIFIED |
| T3 | kid not marked compromised | ISSUER_KEY_COMPROMISED |
| T5 | Replay: the Proof's jti has not been used at this relying party (an atomic write, run only after P1–P14 pass). Store unavailable → SERVICE_UNAVAILABLE | PROOF_REPLAYED / SERVICE_UNAVAILABLE |
| T7 | The answer of the spend: the atomic decrement of the matched Capability's budget. consumed → true; exhausted (another request took the headroom first) → false; store unavailable → SERVICE_UNAVAILABLE. A Capability without budget makes T7 true without a write | AUTHORITY_EXHAUSTED / SERVICE_UNAVAILABLE |
delegus- is T2, T3, T5, T1 strengthened with standing, and T7 (trust configuration trust_0003). delegus-, the policy of a retired intermediate profile, was T1 as in v1, T2, T3, T5 and T7. T4 and T6 do not exist; identifiers are never reused.
Good standing. Delegus staff can suspend a company, or mark it disputed, on a misuse report, and lift that later, with a recorded reason. While a company is not in good standing, every request under its Grants gets a signed DENY with ISSUER_ at T1. A company that is not registered at all still gets ISSUER_. Receipts already signed never change. Standing is checked only for relying parties on delegus-; under delegus-, T1 is unchanged and ISSUER_ stays reserved.
Spec §5.3 defines T1 this way: issuer is a registered Principal in good standing. Standing is Delegus trust data: staff mark a Principal suspended or disputed on a misuse report, with a reason, audited, and lift it the same way. Receipts already issued are never altered.
Evaluation order#
P1 → T1 → T2 → T3 → P2 → P3 → P4 → P5
→ [resolve declared dependencies; read revocation state, including each CURRENT_AUTHORITY dependency's]
→ P6 → P7 → P8 → … → P14
→ [atomic replay write]
→ T5 → P15 → … → P20
→ P21
→ D1 → (per relies_on entry) D2 → D3 → D4 → D5 → D6 → D7
→ [spend: atomic budget decrement, only if every check above is true]
→ T7The bracketed steps are internal operations, not checks. The decision is DENY if any check is false, and reason is the first false check in this order. Dependency checks run after P21 so the agent's own reasons are reported first. The spend is last, so no request spends budget and is then refused.
What each check needs#
A check whose prerequisite did not pass is reported "skipped". P1–P20 and T1–T5 keep their v1 prerequisites (see DENY reason codes). v3 adds:
| Check | Needs |
|---|---|
| P21 | Every earlier check true: P1–P20 and T1, T2, T3, T5 |
| D1–D7 | P21 true |
| D3 … D7, per entry | the previous D-check true for that entry |
| T7 | Every other check true |
So a replayed, revoked, expired or wrongly addressed request never reads or spends budget, and never has its dependencies evaluated.
protocol. differs from v1 when a trust check fails. Because P21 and D1–D7 wait on T1–T3 and T5, a v3 receipt refused by a trust check (for example PROOF_) shows those checks "skipped" and protocol., although no P-check is false. Under v1 the same replay shows protocol.. The decision and reason are the same. Read the reason from reason, never from protocol..
A dependency or budget refusal uses up the Proof. Both come after T5, so the agent needs a fresh Proof to try again.
Earlier version: delegus-base-v1 (v0.2)#
delegus-, with trust policy delegus- and receipt format delegus-, is the v0.2 profile. It stays published and frozen; delegus- is the default. It is kept here for history and for every relying party that has not chosen v3; its receipts keep verifying under v0.2 rules.
delegus-base-v1 (v0.2) | delegus-base-v3 (v0.3 rc1) | |
|---|---|---|
| Protocol checks | P1–P20 | P1–P21, D1–D7 |
| Trust checks | T1, T2, T3, T5 (delegus-trust-v1) | T1 with standing, T2, T3, T5, T7 (delegus-trust-v3) |
| T1 | registered Principal | registered Principal in good standing |
ISSUER_NOT_TRUSTED | reserved, never produced | produced at T1 |
| Action types | commerce:purchase, api:call | adds commerce:quote, commerce:accept, commerce:fulfil |
budget constraint | unknown key, P17 UNKNOWN_CONSTRAINT | defined; checked at P21, spent at T7 |
relies_on / requires | not accepted (ACTION_MALFORMED / HTTP 400 REQUIREMENTS_NOT_SUPPORTED) | accepted |
| Receipt | delegus-receipt-v1, matched Capability in plain text | delegus-receipt-v2, matched Capability pinned by commitment |
| Trust configuration | trust_0001 | trust_0003 |
| Status | frozen, published | release candidate, published |
The full v1 table is at /profiles/delegus-base-v1.
The receipt names the matched authority by authority_ (spec §5.6, §6.2, §6.3, §R.6).
History#
The profile document is pinned by hash in every receipt, so its bytes never change; a change is a new profile with a new name. The published delegus-, served at /profiles/delegus-base-v3, has this hash:
sha256:dffe1a6e71459fc55fb2469689a7c2da6bb2b5abbdcc0091906d8ac06cd374cdOn 25 Sep 2026 an interim build published one revision with a reworded sentence by mistake (the first hash below). It was reverted the same day. No production receipt pins it. It stays retrievable by hash at GET /. Receipts from the development environment may pin it, or an earlier draft (the second):
sha256:c3fb3b6fb525aeca4988da10c1bdd045aaa9ae1c4eaa9f3076a0f309d4efa4be
sha256:fcd03a43febc57e3420c31856b8ef3ca3b4082e3eb0dda5253e2a28c3c613550