Skip to content

delego 0.3.3 — implement the §9 authorization token - #17

Merged
koishore merged 1 commit into
mainfrom
feat/authorization-token
Jun 10, 2026
Merged

delego 0.3.3 — implement the §9 authorization token#17
koishore merged 1 commit into
mainfrom
feat/authorization-token

Conversation

@koishore

Copy link
Copy Markdown
Member

Implements the last spec-ahead item: the §9 authorization token (optional profile). The roadmap's "moat" — and the enforcement-side closure of the agent declared-vs-sent gap.

Protocol unchanged (0.3) — the token is additive, changes no hashed/signed bytes, and is off by default, so existing deployments are byte-for-byte identical. Package → 0.3.3.

What

  • delego/token.py — a compact EdDSA JWS/JWT built on cryptography (no new dependency, no PyJWT):
    • TokenIssuer.mint(...) — short-lived (TTL ≤ 300s, default 45s), minted only for allow / released approval.
    • verify_token(...) — §9.1 checks 1–4: pins EdDSA and rejects none/algorithm-confusion (key comes from verifier config, never the token header), exact aud, expiry + bounded skew, single-use jti/cns.
    • require_fingerprint(claims, action) — §9.1 step 5, the crux: the broker recomputes the fingerprint of the request it's about to send and requires it equals the token's fpr. A token for action A can't release action B; an agent that declared one action but sends another is refused at the PEP. (Closes the SECURITY.md "declared vs. sent" boundary.)
  • Wiring: Firewall(token_issuer=, token_audience=) and build_firewall(mint_tokens=True); token on Decision.token. A separate token_key.pem (distinct from the audit key, spec §9 SHOULD) is generated on first use.
  • Brokers: optional token= kwarg (non-breaking — a bare execute(action) adapter still works); HTTPProxyBroker forwards it to the gateway as authorization_token.

Verification

  • 65 tests (14 new in tests/test_token.py + a broker token-forwarding case): mint-gating (no token on deny/needs_approval/denied/consumed), and every §9.1 failure mode — alg=none, tampered payload, wrong key, wrong aud, expired, TTL>max, jti replay, cns reuse, kid key-selection — plus the step-5 substitution refusal.
  • examples/demo.py green; existing 51 unchanged (feature is opt-in).
  • A follow-up spec PR adds token CTK vectors + wires conformance (installs delego@main, so merge this first).

A portable, signed PDP->PEP decision artifact (spec §9): a compact EdDSA JWS
minted on 'allow'/released approval, verified by a separated broker before it
injects a credential. Built on cryptography (no new dependency).

- delego/token.py: TokenIssuer.mint (allow/release only), verify_token (§9.1
  1-4: pin EdDSA, reject none/alg-confusion with the key from verifier config
  not the header, exact aud, exp+skew, single-use jti/cns), require_fingerprint
  (§9.1 step 5 -- recompute the fingerprint of the request the broker will send;
  the enforcement-side closure of the declared-vs-sent gap).
- Firewall(token_issuer=, token_audience=) / build_firewall(mint_tokens=True);
  token rides on Decision.token. Separate token_key.pem (distinct from the audit
  key, spec §9). Brokers accept optional token=; HTTPProxyBroker forwards it.
- Off by default: protocol unchanged (0.3), existing behaviour byte-for-byte
  identical. Package 0.3.3. 14 new tests (mint gating + every §9.1 failure mode
  + step 5); 65 total green.
@koishore
koishore merged commit 05528a3 into main Jun 10, 2026
3 checks passed
@koishore
koishore deleted the feat/authorization-token branch June 10, 2026 21:40
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