feat: align request signing with AgentWire v0.2 spec#90
Merged
Jing-yilin merged 5 commits intofeat/world-typesfrom Mar 18, 2026
Merged
feat: align request signing with AgentWire v0.2 spec#90Jing-yilin merged 5 commits intofeat/world-typesfrom
Jing-yilin merged 5 commits intofeat/world-typesfrom
Conversation
- Add v0.2 HTTP header signing to outbound requests (peer-client, peer-discovery) with method/path/authority/Content-Digest binding for cross-endpoint replay resistance - Add dual-mode verification on server: prefer v0.2 header signature, fall back to legacy body-only signature for backward compatibility - Add rawBody parser to preserve original body for Content-Digest verification - Refactor response signing to use shared signHttpResponse from identity module - Add AwRequestHeaders/AwResponseHeaders type interfaces - Add 12 new tests covering round-trip signing, tamper detection, replay resistance, timestamp skew rejection, and legacy backward compatibility
…om cross-check - C1: Strip query string from req.url before v0.2 signature verification - C2: Use X-AgentWorld-Version from header in verification signing input instead of hardcoded local PROTOCOL_VERSION (enables rolling upgrades) - W2: Cross-check X-AgentWorld-From header matches body 'from' field - W3: Add TODO for key-rotation dual-mode verification (deferred) - N3: Add empty body Content-Digest test - N4: Add verifyHttpResponseHeaders round-trip test - Add from-mismatch rejection test
Contributor
Author
Codex Review — Findings & FixesCRITICAL (fixed in f99e28d)C1.
C2. Version in signing input used local
WARNINGS (fixed in f99e28d)W2. No
W3.
W1.
W4. Authority format fragility (client vs server)
NOTES (addressed in f99e28d)
Test results: 112 pass, 0 fail |
Reverts the peerPort default introduced in 209b7da. Remote peers almost always listen on the network default 8099; using the local peerPort caused connection refusals when the gateway ran on a non-standard port.
buildManifest() previously only injected hostAgentId/hostCardUrl/ hostEndpoints when config.worldType === 'hosted'. If the manifest was marked hosted via hooks (manifest.type = 'hosted') while worldType was left at its default, joiners received a hosted manifest with no host connection details. Now checks result.type instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Aligns the DAP plugin's request signing with the AgentWire v0.2 spec. Previously, requests used body-only signatures (v0.1 style). Now outbound HTTP requests include
X-AgentWorld-*headers with method/path/authority/Content-Digest binding for cross-endpoint replay resistance.Changes
Client-side (outbound)
peer-client.ts:sendViaHttpnow produces all 6X-AgentWorld-*signing headerspeer-discovery.ts:announceToNodesends v0.2 header-signed announcessignaturefield for backward compat with un-upgraded receiversServer-side (inbound)
peer-server.ts: Dual-mode verification — checksX-AgentWorld-Signatureheader first, falls back to bodysignatureif absentrawBodycontent parser to preserve original body for Content-Digest verificationsignHttpResponsefrom identity moduleShared utilities
identity.ts: AddedsignHttpRequest,verifyHttpRequestHeaders,signHttpResponse,verifyHttpResponseHeaders,computeContentDigesttypes.ts: AddedAwRequestHeaders/AwResponseHeadersinterfacesv0.2 signing input (per spec §6.6)
{"v":"0.2","from":"aw:sha256:...","kid":"#identity","ts":"ISO8601","method":"POST","authority":"host:port","path":"/peer/message","contentDigest":"sha-256=:...:" }Tests
test/request-signing.test.mjscovering:sendP2PMessageend-to-end delivery with v0.2 headersWhat this does NOT change
P2PMessage) unchanged — backward compat preserved