secrets-engine/docs/canonical-request-digest-profile.md

48 lines
2.8 KiB
Markdown
Raw Permalink Normal View History

# 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.