mirror of
https://github.com/block/buzz.git
synced 2026-10-30 14:01:37 +00:00
The three JWKS deployment fields (jwks_uri, refresh_interval_seconds, key_snapshot_hard_deadline_seconds) were absent from AssertionPolicyId. A different endpoint serves different keys; a looser hard deadline extends the valid window beyond what the new policy intends. Both changes must invalidate prepared evidence by moving the policy ID. Introduce JwksSourceContract, a closed value type that: - validates the URI (HTTPS, no credentials/fragment, no bare private-IP) and both timing fields (positive, bounded, refresh < deadline) at construction — invalid values are caught at config time, not at first token verification - is the single source of truth for these fields; IssuerJwksConfig embeds it instead of independently restating the three values, eliminating the silent-drift hazard - is a required parameter to IssuerPolicy::new, included in derive_assertion_policy_id after a domain separator; each of the three fields independently changes the policy ID when mutated (tested) Startup validation replaces per-field URI/timing checks (now redundant since JwksSourceContract::new performs them) with a contract mismatch check — NipFiStartupError::JwksContractMismatch fires when the config contract and policy contract drift apart. Behavior tests added: - assertion_policy_id_moves_when_jwks_uri_changes - assertion_policy_id_moves_when_refresh_interval_changes - assertion_policy_id_moves_when_hard_deadline_changes - assertion_policy_id_is_stable_for_same_jwks_contract (determinism) - key_rotation_does_not_change_assertion_policy_id Each test carries a mutation comment naming the hash-omission that turns it red. JwksSourceContract exported from nip_fi/mod.rs and lib.rs. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>