Skip to content

Commit e3f7d2d

Browse files
committed
docs(agents): add signature and certificate verification rules
Three rules a patch author cannot recover from the code alone, all three found by review rounds on #224 and #236: Anchor the verifying key outside the artifact. Deriving it from a field of the object under verification proves self-consistency, not authenticity, and identities here are permissionless. Found on #236 in the gl client and again on #224 in the server-side twin, where a self-signed certificate verified against an unauthenticated route. Drive the accepting verdict in a test. #224's verify endpoint shipped with sixteen tests, every one asserting the invalid path, which left it unable to observe a forged artifact being accepted. Treat a signed payload's field set as a versioned format. #224 grew it from seven fields to thirteen with no discriminator and no fallback, so every certificate issued before it now reports as tampered.
1 parent 8397a4a commit e3f7d2d

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

‎AGENTS.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Every repo-scoped endpoint must bind the caller to an authorization decision bef
1919
- A new mutation handler also gets a row in `every_in_scope_mutation_has_its_gate` naming its gate type; the per-handler row is the point of that test.
2020
- A table-driven deny suite covering every deny-bearing route is in review (#194, #195). If it is present in your checkout, add a probe row there for any new deny-bearing route.
2121

22+
## Verifying signatures and certificates
23+
24+
- Derive the verifying key from something outside the artifact you are checking: the node's own DID, a pinned or configured value, a peers lookup. A key read from a field of the object being verified (`Did::from_str(&cert.node_did)`) only proves the artifact is self-consistent, and identities here are permissionless, so anyone can mint a keypair, name it in the artifact, self-sign, and be told it is valid. A mismatch against that anchor has to fail the result, not log a warning.
25+
- A handler whose correct answer is "valid" needs at least one test that drives it to valid using an artifact built to be accepted for the wrong reason: well-formed, fully populated, and forged. A suite that only asserts the invalid cases cannot tell "rejects what it should" apart from "accepts everything."
26+
- The fields a signature covers are a versioned format. Adding one invalidates every artifact already signed, so give the payload a version, keep a path that verifies the older form, and add a test that verifies an artifact signed before your change.
27+
2228
## Removing a serving path
2329

2430
When a fix removes a path that used to serve content, the same PR must add a test asserting the removed path now denies. The deletion is what turns that test green; without it the path can quietly come back.

0 commit comments

Comments
 (0)