delego 0.3.3 — implement the §9 authorization token - #17
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 oncryptography(no new dependency, no PyJWT):TokenIssuer.mint(...)— short-lived (TTL ≤ 300s, default 45s), minted only forallow/ released approval.verify_token(...)— §9.1 checks 1–4: pins EdDSA and rejectsnone/algorithm-confusion (key comes from verifier config, never the token header), exactaud, expiry + bounded skew, single-usejti/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'sfpr. 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.)Firewall(token_issuer=, token_audience=)andbuild_firewall(mint_tokens=True); token onDecision.token. A separatetoken_key.pem(distinct from the audit key, spec §9 SHOULD) is generated on first use.token=kwarg (non-breaking — a bareexecute(action)adapter still works);HTTPProxyBrokerforwards it to the gateway asauthorization_token.Verification
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, wrongaud, expired, TTL>max,jtireplay,cnsreuse,kidkey-selection — plus the step-5 substitution refusal.examples/demo.pygreen; existing 51 unchanged (feature is opt-in).delego@main, so merge this first).