mirror of
https://github.com/zap-proto/spec.git
synced 2026-10-30 15:04:03 +00:00
Adds the full delegation-token capability lifecycle to the zap-schema crate, matching the canonical Go runtime (github.com/zap-proto/go/cap) byte-for-byte: - Capability value + ZAP wire (de)serialization. CanonicalBytes is identical to Go: header [0..164) read verbatim + canonical caveats (Kind:u32-LE || len:u32-LE || Value). The in-header Caveats list pointer (relOffset 3420 / length) is reproduced exactly, so the signed bytes match across runtimes regardless of heap layout. - issue() + Capability::attenuate(): mint-time delegation gate (parent needs PermAttenuate or Kind==Delegate), monotonic permission narrowing, child Issuer = parent Holder, shrink-only expiry. Refuses to build a cap its own verifier would reject (SPEC §7). - Verifier::verify() + verify_chain(): every SPEC §2.3 invariant (monotonic perms, holder linkage, target invariance, root zero-Parent, delegation gate, unknown-CaveatKind fail-closed) with FAIL-CLOSED scheme dispatch — Reserved (0x00) and unknown tags refused, Secp256k1/Hybrid refused (no fabricated primitive), never a silent downgrade. - cap_id() = SHA-256(CanonicalBytes || Sig) per SPEC §4 (sha2 crate). - Revocation: revoke() + verify_revocation(), scheme-aware + fail-closed. - Schemes: Ed25519 (ed25519-dalek) mandatory; ML-DSA-65 (pqcrypto-mldsa) real end-to-end; Secp256k1/Hybrid fail-closed errors pending a wired hook. Cross-language KAT (tests/cap_kat.rs + tests/testdata/cap_go_kat.hex): a Go-produced fixture (fixed ed25519 seed 32x0x42, fixed inputs, zero-caveat and two-caveat cases) is decoded in Rust; CanonicalBytes and cap_id match Go byte-for-byte, the Go-signed Ed25519 signature verifies under the known pubkey, and a tampered header is rejected. Proves Go<->Rust cap interop. 35 cap tests green (32 unit + 3 KAT). cargo clippy clean on cap.rs.