TypeScript SDK: frame encoding, canonical request signing and HMAC parity with Python SDK#42
Open
shayankashif123 wants to merge 5 commits intoc2siorg:mainfrom
Open
Conversation
…ry framing, and HMAC signing inputs. transport layer: IPC connection handling, retry logic, and response frame retrieval/decoding.
…idecar interactions
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.
This PR is a direct result of the review comment on the original mixed PR. As requested, the
api/Python FastAPI facade and rules engine have been split out into a separate PR (PR B) so this coreSDK wire-path work can be reviewed and merged independently without getting stalled behind API-level design questions.
This PR contains exactly what the reviewer scoped as PR A:
What changed and why
sdk/typescript/src/frame.ts— canonical signingsortKeysRecursiveandcanonicalPayloadgive the TypeScript SDK deterministic byte-level output for HMAC parity with Python. Every key in the payload object tree is sorted alphabetically beforeserialization — this is the JS equivalent of
sort_keys=TrueinPython's
json.dumps.Without this, two SDKs inserting keys in different orders produce different byte sequences and therefore different HMAC signatures. The sidecar has no way to distinguish that from tampering — it
rejects the request.
sdk/typescript/src/transport.ts— UDS clientUnix Domain Socket client using Node.js
net.createConnection.Signs every payload with HMAC-SHA256 via Node stdlib
crypto— zero external dependencies. Retry logic handles the race condition between agent startup and sidecar readiness.sdk/typescript/src/firewall.ts— Firewall classAsync/await interface for the four v1 hook call sites, mirroring the Python SDK exactly:
sdk/typescript/tests/parity.e2e.ts— parity testsRuns identical payloads through both SDKs against a live sidecar and compares HMAC signatures byte-for-byte. This is the definitive guard that
sortKeysRecursiveandsort_keys=Truestay in sync across future changes..github/workflows/ci.yml— CI additions (Node 20)24 lines adding TypeScript build and test on Node 20 with cache,
wiring up the three npm scripts the Go sidecar expects:
npm run test # unit tests
npm run test:e2e # sidecar integration tests
npm run test:parity # byte-level parity against Python SDK
sdk/python/acf/firewall.py—sort_keys=True(line 146)Directly addresses the parity gap flagged in the review comment:
Python dicts preserve insertion order since 3.7 so this was invisible in simple cases — a developer who always inserts keys
in the same order would never hit it. But any nested object where Python and TypeScript insertion order diverged would produce different HMAC signatures and cause the sidecar to reject
legitimate requests.
sort_keys=Truecloses the parity gap permanently at the source.README.md— prerequisites note for parity testDirectly addresses the nit flagged in the review comment. Added
one line before
npm run test:parity:Testing
What this PR does NOT include
The
api/Python FastAPI facade,api/rules/engine.py,api/models.py,api/config/rules.yaml, anddocs/api.mdhave been moved to PR B as requested. That work needs its own
issue and architectural review from @tharindupr before merging.