Remit token reference¶
Format krt1.
The signature is Ed25519 over the exact payload bytes that were encoded.
key_id names the control-plane key, published at GET /v1/keys. base64url
carries no padding. Unknown prefixes are refused.
Payload¶
{
"rid": "rem_01j6zq…", "parent": "rem_01j6zp…", "run": "run_01j6zr…",
"iss": "key_01j6z…", "iat": 1757000000, "nbf": 1757000000, "exp": 1757086400,
"tools": ["ledger.*", "http.get"],
"scopes": ["sql:table:invoices", "http:host:api.halcyon.example"],
"grants": ["pii"],
"spend": {"tokens": 200000, "usd": 2.0},
"autonomy": "supervised",
"policy_set": ["finance-default"],
"requested_by": {"id": "u-ana", "role": "ap_clerk", "manager": "u-tom"}
}
parent and run are optional. A remit with run set is bound to that run;
it is what workers receive in a lease, and the gateway refuses a call whose
run_id differs (remit_run_mismatch).
Patterns¶
Tool ids are connector.operation; a pattern is an exact id or connector.*.
Scopes are system:kind:key; a pattern may end in * to match a prefix.
Matching is exact-or-glob, case sensitive, without regular expressions.
Autonomy¶
Ordered observe < propose < supervised < autonomous. The gateway
refuses any tool with writes: true under observe and propose: those levels
may read and may propose actions, never write. Policy decides the rest:
the default rule requires the requester's manager to approve a write to a
system of record unless the remit is autonomous.
Verification order at the gateway¶
- Prefix, four parts, base64url decodes.
- Signature valid for
key_id. nbf <= now < exp.run, if set, equals the call'srun_id.- The tool matches a
toolspattern. - The scope the connector derives from the arguments matches a
scopespattern (a connector with no derivation requires the literal<connector>:*). - The operation's
writesflag is allowed byautonomy.
Any failure is a 403 refusal with the reason, a tool.refused event on the
run, and a metric. Spend is enforced by the kernel's budget, not the gateway.
Delegation narrows¶
derive(parent, request) succeeds only when every field is a subset:
| Field | Rule |
|---|---|
tools, scopes |
Each child pattern must be matched by some parent pattern |
grants |
Subset |
spend.tokens, spend.usd |
Less than or equal |
autonomy |
Less than or equal in the order above |
exp / nbf |
Earlier / later |
policy_set |
May grow; removing a policy is a widening |
A violation is 422 remit_widens naming the field. A run may spawn sub-runs
only through derive.
Grants¶
Grants name data classes the run may see un-redacted. Policy reads them
(run.remit.grants("pii")) and the worker's data boundary redacts content whose
class is not granted before it reaches a model provider, recording the
redaction as a note event.