Skip to content

fix(auth): replace a device's own CLI login key instead of accumulating a new one - #1050

Open
AmirF194 wants to merge 2 commits into
tokencanopy:mainfrom
AmirF194:fix/44-cli-login-key-accumulation
Open

AmirF194 wants to merge 2 commits into
tokencanopy:mainfrom
AmirF194:fix/44-cli-login-key-accumulation

Conversation

@AmirF194

Copy link
Copy Markdown
Contributor

Summary

writeCLIHandoffPage minted an API key named "CLI login" on every successful
CLI OAuth callback, with no lookup of an existing key, no revoke, and no
device identity, so every e2a login (or a config wipe) left another
indistinguishable, never-expiring key behind. A key from a lost or wiped
machine had no name that told it apart from a current one, so it stayed live
until someone found and revoked it by hand.

The CLI now appends the machine's hostname as device_name on the browser
login URL (falling back silently if the hostname lookup throws, so a login
never fails over it). The server sanitizes that value to printable ASCII,
capped at 64 characters, and when it is present, names the new key
"CLI login on <device>" and revokes any live key with that exact name
before minting the new one, so re-authenticating from the same machine
replaces its own key instead of adding another. Without a device name (older
CLI binaries, or a login door that never plumbs one in) the server keeps the
old behavior of minting a fresh "CLI login" key every time, since revoking
by that shared, unscoped name could otherwise take out a different device's
still-live key.

No migration: revoked_at and its index already exist on api_keys
(migrations/001_init.sql).

Operational risk

No schema change, no change to the request/response shape of anything under
/v1. device_name is an optional query parameter the login endpoint did
not previously read; older CLI versions that omit it keep today's behavior
exactly. The dashboard's key list will start showing "CLI login on <host>"
names for anyone re-authenticating with the new CLI, alongside any older
plain "CLI login" rows from before the upgrade.

Test plan

  • TestHandleCallback_CLILogin_SameDeviceReplacesPriorKey is the regression
    test: two logins from the same device name leave exactly one live
    "CLI login on <device>" key, and it is the second mint. It does not
    compile against main (no DeviceName field there yet) and passes here,
    alongside TestHandleCallback_CLILogin_NoDeviceName_PreservesLegacyAccumulation,
    which pins that two logins with no device name still leave two distinct
    "CLI login" rows.
  • go test ./internal/auth/... ./internal/identity/... and
    npx vitest run src/__tests__/login.test.ts (cli/) both green.
  • go vet ./internal/auth/... ./internal/identity/... and make fmt-check
    clean.
  • I have not run a live end-to-end OAuth round trip against Google, or the
    Go coverage gate's full per-package floors.

Fixes #44

…ng a new one

writeCLIHandoffPage minted a key named "CLI login" on every OAuth callback with
no lookup of an existing key, no revoke, and no device identity, so every
`e2a login` (or config wipe) added another indistinguishable, never-expiring
key. The CLI now sends the machine's hostname as device_name on the login URL;
the server sanitizes it to printable ASCII (<=64 chars) and, when present,
revokes the caller's prior key of the same device-scoped name before minting
its replacement. Without a device name (older CLI binaries, or a login door
that does not plumb one) the server keeps minting a fresh "CLI login" key, so
it never revokes a different device's still-live key by a shared, unscoped
name.

Fixes tokencanopy#44
@AmirF194
AmirF194 requested a review from jiashuoz as a code owner September 27, 2026 05:36
…accumulation

# Conflicts:
#	cli/CHANGELOG.md
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.

e2a login accumulates API keys per invocation; align with per-device behavior

1 participant