Repository navigation
feat(attestation): one canonical signed-request check and an opaque VerifiedWrite (aegis-2idcev) - #820
Conversation
…cev) The receiver's existing tests are v1-only, so a regression in the v2 audience or in settlement under the writer lock could not turn any of them red (found while sabotaging #820's shared core). This drives the real middleware verify and the writer-lock settle with quipu-write-v2: - signed for this store: admitted; - signed for another store: refused, audience mismatch; - signed for another store with the claim relabelled to this one: badsig; - valid at the pre-check, revoked while queued: refused at settlement as revoked, with the nonce left unspent. Sabotages that now turn it red: the audience taken from the envelope, and settlement that skips the revocation re-check (the queued-revocation control the receiver design requires). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzgSY2LpdGhBhb7D1nHbiF
…erifiedWrite (aegis-2idcev) Slice 1 of the receiver packet designed on aegis-2idcev (2026-10-14). The canonical verifier was reachable only inside the HTTP middleware's private verify, mixed with axum parsing, the route allowlist, identity installation and finalization. It is now quipu::verified_write: - check_signed_request: the one check of a signed request's exact bytes: size bound, body hash computed from the bytes, the receiving store's own id as the v2 audience (never the envelope's claim), every binding check, and whether the nonce is already spent. The HTTP middleware calls it, so there is one verifier; HTTP behaviour is unchanged (its tests pass byte-unchanged). - verify_signed_write: additionally requires a store-audience-bound write-v2 envelope (no v1 downgrade) and an audited write route, and returns VerifiedWrite: private fields, read-only views, no public constructor, Clone, deserializer or conversion from Identity or PendingAttestation. It spends nothing and authorizes no effect; the writer-barrier dispatch is slice 2. ATTESTED_PATHS and the body limit move to the library unchanged. No new route or caller. Tests: v2 positive with exact bytes, audience and unspent nonce; the same signature over a different body, method, path or content type; signed for another store (audience mismatch) and with the claim relabelled (badsig); v1 refused by verify_signed_write but accepted by the core for HTTP; an unaudited route; an oversize body; a spent nonce; another key; an empty signature; an unregistered session; revocation. Five sabotages (v1 downgrade, route, size, audience from the envelope, spent read) each turn a core test red. The HTTP write_attest tests stay green under the audience and spent-read sabotages: they are v1-only, a pre-existing gap now covered by the shared core's tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzgSY2LpdGhBhb7D1nHbiF
…cev) The receiver's existing tests are v1-only, so a regression in the v2 audience or in settlement under the writer lock could not turn any of them red (found while sabotaging #820's shared core). This drives the real middleware verify and the writer-lock settle with quipu-write-v2: - signed for this store: admitted; - signed for another store: refused, audience mismatch; - signed for another store with the claim relabelled to this one: badsig; - valid at the pre-check, revoked while queued: refused at settlement as revoked, with the nonce left unspent. Sabotages that now turn it red: the audience taken from the envelope, and settlement that skips the revocation re-check (the queued-revocation control the receiver design requires). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzgSY2LpdGhBhb7D1nHbiF
324d957 to
1eef9dc
Compare
|
Head 1eef9dc (rebased onto main bb9254c; range-diff shows both commits Added
Sabotages: taking the audience from the envelope, and settlement skipping the revocation re-check, now turn it red. Gates: server 242/0 (pre-rebase); after the rebase, write_attest 7/7, verified_write 6/6, clippy full rc 0, file size and witnesses clean. Re-classified; fresh CI is owed. |
|
Non-author Ian — SOURCE APPROVE at Native T2 INPUT Checked the extracted canonical verifier against the prior HTTP implementation: exact-byte hashing, receiving-store audience, binding validation and spent-nonce read remain shared; the HTTP adapter retains its route/identity/settlement barriers. Validation: all six supplied core tests plus one independent valid-input ownership/no-write/no-spend control PASS. HOME guard inner Landing constraint: do not use |
Slice 1 of the receiver packet designed on aegis-2idcev (2026-10-14).
The canonical verifier was reachable only inside the HTTP middleware's
private verify, mixed with axum parsing, the route allowlist, identity
installation and finalization. It is now quipu::verified_write:
size bound, body hash computed from the bytes, the receiving store's own
id as the v2 audience (never the envelope's claim), every binding check,
and whether the nonce is already spent. The HTTP middleware calls it, so
there is one verifier; HTTP behaviour is unchanged (its tests pass
byte-unchanged).
write-v2 envelope (no v1 downgrade) and an audited write route, and
returns VerifiedWrite: private fields, read-only views, no public
constructor, Clone, deserializer or conversion from Identity or
PendingAttestation. It spends nothing and authorizes no effect; the
writer-barrier dispatch is slice 2.
ATTESTED_PATHS and the body limit move to the library unchanged. No new
route or caller.
Tests: v2 positive with exact bytes, audience and unspent nonce; the same
signature over a different body, method, path or content type; signed for
another store (audience mismatch) and with the claim relabelled (badsig);
v1 refused by verify_signed_write but accepted by the core for HTTP; an
unaudited route; an oversize body; a spent nonce; another key; an empty
signature; an unregistered session; revocation. Five sabotages (v1
downgrade, route, size, audience from the envelope, spent read) each turn
a core test red. The HTTP write_attest tests stay green under the audience
and spent-read sabotages: they are v1-only, a pre-existing gap now covered
by the shared core's tests.
Gates (head 8b0e7a5, base d68a89a)
--features full241/0 (write_attest tests byte-unchanged)-D warnings -A missing-docsrc 0 forfullandshacl,owl; wasm32 check PASS (module native-only)Not in this PR:
dispatch_verified_write(writer barrier, nonce settlement under the same lock, async identity isolation) is slice 2. Default-off; no runtime change.🤖 Generated with Claude Code
https://claude.ai/code/session_01BzgSY2LpdGhBhb7D1nHbiF