Skip to content

fix(hub): add client token revocation (Store.RevokeClient + Revoke RP…#134

Merged
josealekhine merged 2 commits into
ActiveMemory:mainfrom
Ayshine:fix/95-hub-token-revocation
Jul 14, 2026
Merged

fix(hub): add client token revocation (Store.RevokeClient + Revoke RP…#134
josealekhine merged 2 commits into
ActiveMemory:mainfrom
Ayshine:fix/95-hub-token-revocation

Conversation

@Ayshine

@Ayshine Ayshine commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

…C + ctx hub revoke)

The hub could mint client tokens but never retract one: a leaked token stayed valid forever, and the only mitigation was wiping the persistence dir, which invalidated every other client at once.

This adds a revocation path across all three layers:

  • Store.RevokeClient(id) removes a client by stable ID, rebuilds the token index coherently, and rewrites clients.json atomically (new saveJSONAtomic helper) so a torn write cannot corrupt the whole registry.
  • An admin-token-gated Revoke RPC + handler (mirrors Register's admin auth), wired via PathRevoke + makeRevokeHandler.
  • A Client.Revoke wrapper and ctx hub revoke <client-id> command, taking the admin token from --token or $CTX_HUB_ADMIN_TOKEN and the hub address from the saved connection config.

Revoked tokens fail ValidateToken immediately (no in-memory staleness). Also pins the already-implemented duplicate-project rejection with a regression test.

Closes #95.

…C + ctx hub revoke)

The hub could mint client tokens but never retract one: a leaked
token stayed valid forever, and the only mitigation was wiping the
persistence dir, which invalidated every other client at once.

This adds a revocation path across all three layers:
  - Store.RevokeClient(id) removes a client by stable ID, rebuilds
    the token index coherently, and rewrites clients.json atomically
    (new saveJSONAtomic helper) so a torn write cannot corrupt the
    whole registry.
  - An admin-token-gated Revoke RPC + handler (mirrors Register's
    admin auth), wired via PathRevoke + makeRevokeHandler.
  - A Client.Revoke wrapper and `ctx hub revoke <client-id>` command,
    taking the admin token from --token or $CTX_HUB_ADMIN_TOKEN and
    the hub address from the saved connection config.

Revoked tokens fail ValidateToken immediately (no in-memory
staleness). Also pins the already-implemented duplicate-project
rejection with a regression test.

Closes ActiveMemory#95.

Signed-off-by: Ayshine <28358926+Ayshine@users.noreply.github.com>
@Ayshine Ayshine force-pushed the fix/95-hub-token-revocation branch from 7ba594e to d50da6a Compare July 11, 2026 14:40
…mmand

CI on the revocation PR flagged two issues, both mechanical:
  - golangci-lint gosec G101 flagged DescKeyHubRevokeToken as a
    hardcoded credential (its value has enough character diversity
    to cross gosec's entropy threshold, unlike the sibling
    connection.token). It is an i18n desc key; suppress inline,
    matching how the repo handles the same false positive elsewhere.
  - TestDocGoSubcommandDrift requires every cmd/<name>/ directory to
    be documented in the package doc.go. Add revoke to the hub
    package's Subcommands and Subpackages lists.

Signed-off-by: Ayshine <28358926+Ayshine@users.noreply.github.com>
@josealekhine

Copy link
Copy Markdown
Member

Perfection 🤌 .

@josealekhine josealekhine merged commit d3cd880 into ActiveMemory:main Jul 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hub: add token revocation surface (Store method + RPC + CLI); tokens currently valid forever

2 participants