Align authorization request digests with Go canonical wire profile
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
d5ff4c7421
commit
3ffb6a138e
7 changed files with 399 additions and 9 deletions
47
docs/canonical-request-digest-profile.md
Normal file
47
docs/canonical-request-digest-profile.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# 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.
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
{
|
||||
"schema": "source-preparation-receipt/v1",
|
||||
"record_id": "SECRETS-CANONICAL-20261011-R1",
|
||||
"completed_preparation_record_sha256": "c29911e5908ca757d5572530741660438c3d9d1b8962b2ae605cac399ca550f7",
|
||||
"formal_owner_review": false,
|
||||
"native_execution": false,
|
||||
"counterexample_source": "/tmp/access-platform-compiler-review-receipt/docs/evidence/2026-10-11-task-execution/compiler-canonical-counterexample.json",
|
||||
"counterexample_sha256": "eadd598e7ffceaf1431bb5ec3642afa8c230604da1422d324c21dba4d6411c45",
|
||||
"go_oracle_source_sha256": "21e754617c2b82d673cef31b7075f8d177e4367782b63b20b37125587bf9e300",
|
||||
"checks": {
|
||||
"go_oracle_tests": 34,
|
||||
"deterministic_float_samples": 256,
|
||||
"focused_final": 186,
|
||||
"original_fixture_files_modified": false
|
||||
},
|
||||
"prior_observations": [
|
||||
{
|
||||
"kind": "incomplete_stage",
|
||||
"result": "Initial collection errors / missing repo assets; full tracked asset copy corrected staging only."
|
||||
},
|
||||
{
|
||||
"kind": "sandbox_custody",
|
||||
"result": "Initial full staged suite 612 passed, 16 failed, 1 skipped before fractional-support revision. Initial receipt proved only one unchanged-source reproduction. Revision r2 now runs the exact same sixteen failures against unchanged authoritative source, all sixteen reproduce untrusted-owner failure in this sandbox. Full final revised suite is not claimed green."
|
||||
},
|
||||
{
|
||||
"kind": "superseded_preparation",
|
||||
"result": "Initial integer-only float profile superseded before frozen candidate; final admits finite fractional binary64 values."
|
||||
},
|
||||
{
|
||||
"kind": "outside-sandbox-baseline",
|
||||
"result": "Unmodified actual source reproduces TypeError for companion-lane stub missing auth_args; all other custody failures disappear outside sandbox. Exact baseline log retained. Revised test accepts auth_args and verifies identity while preserving each-lane denial/backend refusal test."
|
||||
}
|
||||
],
|
||||
"limits": [
|
||||
"No policy or Go global algorithm change",
|
||||
"No reinterpretation of prior served approvals",
|
||||
"Large Python integers outside safe binary64 interval fail closed",
|
||||
"No native proof or rollout",
|
||||
"Independent review remains required"
|
||||
],
|
||||
"revision": "r3-existing-test-stub-contract",
|
||||
"supersedes_receipt_sha256": "7776fd99177e97a3dfc167e8207d1cdeedecc7bb62ed3f9a53c379946dceb49d",
|
||||
"baseline_verification": {
|
||||
"unchanged_original_code_sha256": "0ec4c3f7304d68abd06a0d08dc459e4f1f7269da0e4258549662be9e57b39fd3",
|
||||
"same_sandbox_environment": true,
|
||||
"observed_tmp_owner_uid": 65534,
|
||||
"executing_uid": 1000,
|
||||
"tests_requested": 16,
|
||||
"same_failures_reproduced": 16,
|
||||
"per_test": [
|
||||
{
|
||||
"test": "tests/test_exec_owner.py::test_actual_bound_child_gets_only_selected_secret_and_fixed_environment",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner.py::test_config_changed_during_fetch_does_not_launch",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner.py::test_binding_changed_after_approval_refuses_before_fetch",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_companion_value_reaches_bound_child_and_is_redacted",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_companion_fetch_failure_starts_no_child",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_each_lane_is_gated_separately_before_backend",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_unresolvable_companion_refuses_before_any_gate",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[missing]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[extra]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[env]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[field]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[lane]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[consent]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_exec_owner_companions.py::test_delivery_rechecks_companion_contract_before_any_read[stage]",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_human_control.py::test_real_exec_handler_rejects_undeclared_claim_before_consume_backend_child",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
},
|
||||
{
|
||||
"test": "tests/test_integration_companions.py::test_two_lanes_reach_one_bound_owner",
|
||||
"result": "failed",
|
||||
"observed_failure": "exec owner path has an untrusted owner"
|
||||
}
|
||||
],
|
||||
"baseline_observation_path": "/tmp/secrets-canonical-baseline-sixteen-observation.json",
|
||||
"baseline_observation_sha256": "652badb08358ae90ea01d7777bd9c26b8778d38b1dc78b97f1fb4ee36dfd40ab",
|
||||
"baseline_log_path": "/tmp/secrets-canonical-baseline-sixteen-tests.txt",
|
||||
"baseline_log_sha256": "fa88af7b7c14780c63a7609d9da329688a53146aecb98a3b2b1ec736d6baf2c6",
|
||||
"staged_full_log_path": "/tmp/secrets-canonical-go-final-tests.txt",
|
||||
"staged_full_log_sha256": "67339d0b2045081f4df67c61e2388df507413057f417d9dd2d77da207fc0bb3e",
|
||||
"full_final_revised_suite_green": true
|
||||
},
|
||||
"full_final_source_suite": {
|
||||
"exit_code": 0,
|
||||
"environment": "outside filesystem sandbox with explicit approved escalation",
|
||||
"collected": 637,
|
||||
"passed": 636,
|
||||
"skipped": 1,
|
||||
"log_path": "/tmp/secrets-canonical-v3-full-suite.txt",
|
||||
"log_sha256": "b563940c02dfa8b8509dacb48ece3f017c2c841690cda37f0a51e6c7ba2203e0",
|
||||
"collection_log_path": "/tmp/secrets-canonical-v3-collection.txt",
|
||||
"collection_log_sha256": "40689fd881e4b16fffcf693b54e05fa169073e7abd884b44642a252d0236bf77",
|
||||
"baseline_stub_failure_log_path": "/tmp/secrets-canonical-baseline-unsandboxed.txt",
|
||||
"baseline_stub_failure_log_sha256": "92fd5edb071e1b74a0971642226e532b8f2edc9284b411339335f370c3816f1b",
|
||||
"baseline_stub_exit_code": 1,
|
||||
"canonical_code_sha256_unchanged_from_r1": "d58e5fd01ca2470a5d11a6b4f7e9d262a0c1565637e07b35466faa30e4991d14",
|
||||
"native_estate_changes": false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"schema": "bounded-source-preparation/v1",
|
||||
"record_id": "SECRETS-CANONICAL-20261011-R1",
|
||||
"driver": "SECRETS-WP-0013-T01",
|
||||
"status": "completed",
|
||||
"scope": "Local canonical digest consumer repair and source tests only",
|
||||
"formal_owner_assent": false,
|
||||
"native_execution": false,
|
||||
"workplan_task_status_change": false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue