feat: agentgate v0.2.0 — CLI, version check, tests, pathPrefix - #4
Merged
Conversation
Four hardening items for customer delivery: 1. VERSION export + CLI --version + upgrade --check against GitHub Releases (exit codes 0/10/20, graceful degradation) 2. CLI bin (agentgate): keygen, register, keys list, keys revoke with security rules (ops token from env only, private key never printed, 0600 perms) 3. keygen + register unit tests (node:test, mock fetch, no live network) — 52 new tests 4. pathPrefix on signRequest/AgentSigner/createSigner: signature covers the internal path after proxy prefix stripping, eliminating silent 401 errors 135 tests total, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
owen0x6f
approved these changes
Aug 5, 2026
owen0x6f
left a comment
There was a problem hiding this comment.
Reviewed at d712b4d. Approving — all five items delivered and correct, 8/8 checks green, golden-vector integrity preserved (byte-compat with the Go side intact).
Verified:
- pathPrefix: strips the proxy-stripped prefix and signs the internal path;
|| '/'fallback when path == prefix; no-op when prefix doesn't match. This is the fix for the silent-401 trap. Good. - upgrade --check: GitHub Releases source, graceful degradation for rate-limit/404/timeout/ENOTFOUND, exit codes 0/10/20 mapped in the CLI;
--jsonstill sets the exit code. - CLI security: ops token read only from
AGENTGATE_OPS_TOKEN(no token flag exists), private key never printed (only kid/pubkey/fingerprint/path), 0600 via savePrivateKey. - Tests: keygen + register + pathPrefix, fetch injected, no live network.
Two minor, non-blocking hardening notes (fine to defer to a later tidy, not gating this merge):
signRequestprefix match usespathname.startsWith(pathPrefix). A theoretical path like/ajj/agentXwould strip toX(no leading slash). Not a real route, and worst case is a 401, not a security hole — butpathname === pathPrefix || pathname.startsWith(pathPrefix + '/')is more robust.semverComparedoesn't handle pre-release tags (0.2.0-rc1→ NaN segment compares equal). We control our own clean release tags, so it won't bite; noting for completeness.
Merging + cutting v0.2.0 so upgrade --check has a source of truth.
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
Hardening agentgate for customer delivery. Single PR, target v0.2.0.
1. Versioning + upgrade check
VERSIONexported fromsrc/index.js, read frompackage.jsonagentgate --version/agentgate versionagentgate upgrade --check [--json]queries GitHub Releases0(up to date),10(upgrade available),20(check failed)2. CLI (
bin)agentgate keygen --kid <id> [--out <path>]agentgate register --kid <id> --tenant <t> --agent <a> --cp-url <url>agentgate keys list/keys revokeAGENTGATE_OPS_TOKENenv var only (never CLI args); keygen writes 06003. keygen + register tests
test/keygen.test.js: key type, base64 export round-trip, fingerprint, save/load, 0600 permission enforcement, seed determinism, path sanitizationtest/register.test.js: URL construction, body shape (exactlykid/alg/pubkey_b64),alg="Ed25519"(capital E), error mapping (only 500 retryable),request_idpass-through, revoke/list_fetch, no live network4. Signing path prefix (pathPrefix)
signRequest,AgentSigner,createSigneracceptpathPrefix/ajj/agent/api/v1/query→ signs/api/v1/query)/; non-matching prefix is no-opStats
Spec
https://mike.coco.site/pages/s/49a2efe0fbbb8eddee6aa0039069c60d (password: 100735)
Test plan
npm test— 135 tests greenagentgate --version→0.2.0agentgate upgrade --check --json→ exit 20 (no releases yet), correct JSONagentgate keygen --kid test→ generates key, 0600 perms🤖 Generated with Claude Code