Raxol. AgentClientProtocol. Ext. Capability. Token
(Raxol Agent Client Protocol v0.1.0)
Copy Markdown
View Source
The RXC1 capability token — offline-verifiable detached Ed25519 signature.
The headline capability: an attach to a writerless session (a tar'd journal directory, no live authority, no network, no issuer reachable) is authorized cryptographically from the token bytes + a shipped public key ALONE.
Encoding — version-pinned, no alg field anywhere
token := "RXC1." <> b64url_nopad(claims_json) <> "." <> b64url_nopad(sig)
signing_input := "RXC1." <> b64url_nopad(claims_json) # prefix INCLUDED in signed bytes
sig := Ed25519-sign(issuer_priv, signing_input) # 64 bytes, detachedEncoding rules, each load-bearing:
- No header, no
alg. The literal prefixRXC1is the algorithm binding (RXC1 ⟺ Ed25519). The JWTalg:none/ RS256→HS256 confusion is structurally UNEXPRESSIBLE — no code path reads an algorithm name. - The prefix is inside the signed bytes, so a signature minted for a
hypothetical
RXC2can never be replayed underRXC1(downgrade). - The signature covers the encoded blob, not re-canonicalized JSON. The verifier base64url-decodes and JSON-decodes but NEVER re-encodes — there is no canonicalization step, hence no malleability class (key ordering, unicode escaping, duplicate keys are all bound by the signed bytes).
- Strict base64url,
padding: false. Any=/+///whitespace/ non-alphabet byte ⇒ decode failure ⇒ deny. Exactly three dot-separated non-empty segments — one token has exactly one valid byte form.
Verification is TOTAL
verify/4 is a pure function: same inputs ⇒ same output; no network, no
process dictionary, no clock read (now is a parameter), no filesystem.
For ALL binaries it returns {:ok, claims} | {:error, atom} — never raises,
never creates an atom. Reason atoms are internal
(telemetry only); the wire sees a single bare deny (anti-oracle).
Summary
Functions
The iat clock-skew tolerance (seconds). exp has none.
The restrictive claim keys this verifier IMPLEMENTS (enforce-if-present).
Verify a token against a keyring, wall-clock now (unix seconds), and the
expected session id. Total: every failure is {:error, atom}, never a raise.
Types
Functions
@spec clock_skew_s() :: non_neg_integer()
The iat clock-skew tolerance (seconds). exp has none.
@spec restrictive_implemented() :: [String.t()]
The restrictive claim keys this verifier IMPLEMENTS (enforce-if-present).
Verify a token against a keyring, wall-clock now (unix seconds), and the
expected session id. Total: every failure is {:error, atom}, never a raise.