You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[RefImpl] Consolidate AGT wire signing, config and protocol constants into a shared acs-wire package #230
Hardening the existing AGT reference implementation (reference-implementations/agt/, TypeScript on Bun).
What this proves
That ACS signing and canonicalization can live in one small package that both the Guardian and a host import. §10 requires both sides to compute the same canonical input, and today each side carries its own copy.
This is the refactor @afogel proposed in the review of #229. It was deferred from that PR so the PR stays reviewable.
1. Add a shared packages/acs-wire package (server.ts:658). Its only dependency is node:crypto. The host still never imports the Guardian.
protocol.ts: ACS_VERSION, the §17.1 AcsError codes, AcsSignature and the algorithm names.
jcs.ts: one RFC 8785 implementation. Today there are two, in verify-signature.ts and sign-envelope.ts.
authenticator.ts: createHmacAuthenticator(ikm) and NULL_AUTHENTICATOR, which implement a RequestVerifier role for the Guardian and a RequestSigner role for the host. HKDF derivation moves in here, and there is one copy of it.
2. Guardian: verify each request once. Remove the inline check at server.ts:864–886, requestHasValidSignature, extractSessionId, the five base64 decodes of the secret, and every if (hmacSecret) branch. buildServerHello reads authenticator.algorithms.
3. Host: let GuardianClient sign as well as verify (govern-step.ts:665). Remove the hmacSecret option from governStep, from negotiateSessionConfig and from OpenCode's Deployment, and delete sign-envelope.ts.
4. Read ACS_HMAC_SECRET once, through one validator (acs-hook.ts:536). Use strict base64 and a 32-byte minimum. Today both hosts silently run unsigned when the variable is empty and accept short keys. Also:
Fail loudly when signing is required but the host has no key.
5. Give each constant one source, split by owner (handshake.ts:116).
Values fixed by the spec go in acs-wire/protocol.ts. These are the version, the error codes, the algorithm names and the signature type. The host's REFUSAL_RPC_CODES is then built from the named codes instead of a copied list.
Values chosen by the deployment go in the Guardian's config. These are the skew window, timeouts, replay-store limits and the minimum key length. ServerHello and the timestamp check then read the same skewWindowMs and cannot drift apart.
Done when no secret is decoded outside the authenticator, and JCS and HKDF each exist once.
Do you intend to implement this yourself
Yes, I want this assigned to me
Current Priority Scope
Feeds the runnable Guardian reference implementation
Activity