fix(gateway): verify client signature before payload_hash #41
Reference in New Issue
Block a user
Delete Branch "feature/issue-39-verification-order"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Make the gateway verify the client signature before the
payload_hash, matchingdocs/ARCHITECTURE.md§15 "Verification order".Why
ARCHITECTURE.md§15 lists the signature (step 4) beforepayload_hash(step 5), but the authenticated-edge decorator chain ingateway/internal/grpcapi/server.gowrapped the payload-hash gate outside the signature gate, so the hash was checked first.gateway/README.mdandgateway/docs/flows.mdhad drifted to match the code (hash-first), leavingARCHITECTURE.mdas the only source describing the intended order.Signature-first is the cryptographically sound order: the signature covers the
payload_hashfield, so the request is authenticated before any of its content is processed. Per the owner's decision on #39 (option A): move the code underARCHITECTURE.mdand bring the other docs in line.Changes
server.go: swap the two decorators sonewSignatureVerifyingServicewrapsnewPayloadHashVerifyingService(signature runs first).payload_hash.go/signature.go: update the decorator doc comments to the new order.gateway/README.md(steps 5↔6) andgateway/docs/flows.md(mermaid): align to signature→hash.payload_hash_integration_test.go: re-sign the four tests over the tampered hash so they keep exercising the hash gate (otherwise the signature gate, now first, would reject them withUNAUTHENTICATED).Observable side effect
A request with a tampered
payload_hashwhose signature was computed over the original hash is now rejected at the signature gate (UNAUTHENTICATED "invalid request signature") instead of the hash gate (INVALID_ARGUMENT). Security is unchanged — both refusals occur before the payload is handled. The cross-service integration test (TestGatewayEdge_PayloadHashMismatch) signs over the overridden hash and already accepts both codes.Tests
gofmt -l(changed files) andgo vet ./gateway/internal/grpcapi/— clean.go test -count=1 ./gateway/...— pass.go vet ./integration/...— compiles.Closes #39
🤖 Generated with Claude Code