Skip to content

Harden draft 0.3 clauses: query canonicalization (§4.2) + authorization token (§9) - #3

Closed
koishore wants to merge 1 commit into
Delego-Dev:mainfrom
koishore:spec-0.3-token-query-hardening
Closed

Harden draft 0.3 clauses: query canonicalization (§4.2) + authorization token (§9)#3
koishore wants to merge 1 commit into
Delego-Dev:mainfrom
koishore:spec-0.3-token-query-hardening

Conversation

@koishore

@koishore koishore commented Jun 4, 2026

Copy link
Copy Markdown
Member

What & why

Refines the draft 0.3 clauses (tagged 0.3, draft — not yet in reference) after a close read of the 0.3 frontier. No change to implemented 0.2 behaviour, the receipt payload, the canonicalization of shipped fields, or any existing CTK vector.

§4.2 — query canonicalization, now exact. The prior text ("parsed into [name,value] pairs, sorted") left a parser-differential gap — the exact class of bug this protocol exists to prevent. Now specified precisely: fragment exclusion, split on the first =, RFC 3986 percent-decoding with +→space, repeat/duplicate preservation, code-point ordering. Also clarified that policy (§5) evaluates params onlyquery is bound by the fingerprint but not policy-evaluated, so decision-relevant values must live in params.

§9 / §9.1 — authorization-token hardening.

  • Verifier MUST pin alg = EdDSA, reject none, and MUST NOT take the algorithm or kid from the unverified header — closes the classic JWT algorithm-confusion hole (prior step 1 only said "verify the signature").
  • Token signing key SHOULD be distinct from the audit-chain key, so a token-minting compromise can't forge audit history; kid added to the header for rotation.
  • exp MUST NOT exceed 300 s (was SHOULD ≤ 60 only); clock skew SHOULD be ≤ 60 s.
  • A Broker verifying across instances MUST share jti state (cross-instance replay was unaddressed).
  • Noted that jti is not in the signed receipt payload, so token and receipt aren't cryptographically linked — flagged as a candidate future breaking change rather than slipped in.

§11 — added algorithm-confusion and key-separation considerations. CHANGELOG updated under [0.3-draft].

AI assistance disclosure (required)

  • AI-assisted. Tool(s) and how used: drafted with Claude Code (Anthropic) — a structured review of the draft 0.3 clauses (§4.2, §9/§9.1, §11) and the resulting spec.md / CHANGELOG.md edits. Awaiting the maintainer's line-by-line review; the human author is accountable per CONTRIBUTING.

Kind of change

  • Normative change — but to draft, not-yet-in-reference clauses only.

Checklist

  • Forked the repo; this PR comes from a branch in my fork.
  • python validate.py is green (examples/vectors validate against the schemas).
  • python conformance.py is green (reference 0.2 ≤ spec 0.3; every CTK vector reproduced).

For a normative change (additionally)

  • CTK vectors regenerated from the reference — N/A: §4.2/§9 are 0.3, draft — not yet in reference. Per the spec-leads-reference model (and the existing CHANGELOG note), they ship CTK vectors when the reference implements them. No 0.1/0.2 vector changes; conformance.py stays green.
  • Clauses remain tagged (0.3, draft — not yet in reference); the §2.1 matrix already lists 0.3 — unchanged (refinement, no new clause).
  • The spec leads the reference: reference stays 0.2 ≤ spec 0.3 (conformance confirms).
  • Receipt/canonicalization version bump — N/A this PR: §4.2 is already 0.3-draft and already flagged breaking-on-implementation; this sharpens the draft preimage without changing its unimplemented status or any shipped field. The version bump happens when 0.3 lands in the reference.

…on token (§9)

Refines the 0.3 draft (not-yet-in-reference) clauses only; no change to
implemented 0.2 behaviour, the receipt payload, shipped-field canonicalization,
or any CTK vector.

§4.2 — exact query canonicalization (fragment exclusion, split on first '=',
RFC 3986 percent-decoding with '+'→space, repeat/duplicate preservation,
code-point ordering); clarified policy evaluates params only (query is bound,
not evaluated).

§9/§9.1 — token hardening: verifier MUST pin alg=EdDSA (reject none / algorithm
confusion) and never trust the unverified header; token key SHOULD be separate
from the audit key; kid added for rotation; exp MUST NOT exceed 300 s; skew
SHOULD be ≤60 s; cross-instance brokers MUST share jti state; noted token↔receipt
non-linkage.

§11 — algorithm-confusion + key-separation considerations. CHANGELOG updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant