secrets-engine/docs/canonical-request-digest-profile.md
tegwick 3ffb6a138e
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Align authorization request digests with Go canonical wire profile
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 19:47:45 +02:00

2.8 KiB

Access request digest interoperability profile

Source-only consumer repair, 2026-10-11. The authoritative algorithm remains Access Engine api.RequestDigest / api.ApprovalBindingDigest using Go encoding/json. The opaque sha256: prefix is unchanged. This is not a policy change, native authorization or reinterpretation of a previously served approval. Existing served approvals retain their original immutable request and digest; a mismatching request needs a new request/approval rather than rewriting evidence.

The consumer matches literal UTF-8 Unicode, JSON control-character escaping, Go's default HTML escaping of <, > and &, and unconditional escaping of U+2028/U+2029, including nested map keys. Invalid Unicode scalar strings fail closed. Struct fields retain their documented order; nested maps sort by key. Empty optional attribute maps and context are omitted, matching Go's struct tags. The optional top-level advisory purpose is hashed if present; this does not admit it on enforcement requests, whose Access endpoint rejects that field.

Numeric profile

Access HTTP decoding puts JSON numbers in map[string]any into binary64 float64; arbitrary Python JSON serialization is therefore not equivalent. This consumer admits finite binary64 floats using shortest round-trip digits, Go's fixed notation interval [1e-6, 1e21), normalized scientific exponents, integer-valued float formatting and signed negative zero. Integers outside [-(2^53-1), 2^53-1] fail closed to prevent silently hashing the rounded value Go would decode. Non-finite values and unsupported non-JSON values fail closed. Fractional finite values and Unicode catalogue names remain supported. This profile uses the actual HTTP JSON decode path; arbitrary Go-native values such as json.Number or pre-HTTP big integers are not claimed to match.

Separate fingerprints

execution_contract.catalog_target_digest remains the descriptor-local sorted JSON UTF-8 fingerprint without Go HTML escaping. Approval Engine's claim-binding digest and owner body hashes retain their distinct algorithms. Only full Access request and approval-free Access binding digest computation uses this profile. Removing context.approval reproduces the pre-claim request digest; a full claim-bearing request continues to hash the entire approval claim.

Verification

The new tests build a real oracle against the installed Access Engine source and call its exported digest functions after actual json.Decode. They cover Unicode/HTML/separators, nested keys, exact approval joins, optional omission, supported integer boundaries and explicit unsupported-number refusals. Existing normal canonical/replay/approval/descriptor fixtures remain unmodified. No Go algorithm, policy package, credentials, default or deployment is changed.