Skip to content

Revoke the token fizzy signup created when logging out - #223

Open
jeremy wants to merge 4 commits into
masterfrom
logout-revokes-minted-token
Open

jeremy wants to merge 4 commits into
masterfrom
logout-revokes-minted-token

Conversation

@jeremy

@jeremy jeremy commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Summary

fizzy signup creates a write token ("Fizzy CLI") for the account it sets up. Until now fizzy auth logout only forgot it, so the token stayed valid at Fizzy until someone revoked it by hand. Logout now revokes that token first, then removes it as before.

  • Only the CLI's own token. A token given to fizzy auth login is still only removed. It may also live in a password manager, CI or another tool, so it isn't the CLI's to revoke. The help text says so.
  • How the CLI knows which token it created. saveSignupConfig records the token's SHA-256 (never the token) under the profile's minted_token_sha256. Any other save through saveProfileCredentialState, such as auth login, drops that mark. Logout revokes only a stored token whose digest matches. A stale mark next to a different token matches nothing, so a pasted token is never revoked, whichever path stored it.
  • Best effort, reported. The request is POST <profile base URL>/oauth/revocation (RFC 7009), with a 10 s timeout and no redirects followed. Fizzy accepts a personal access token there on possession and answers 200. Any other answer, or no answer, still removes the credential, prints a warning on stderr pointing at Fizzy's access tokens, and sets revoke_error. The result now carries revoked: true|false. --all does the same for every profile.

Compatibility

  • Profiles and tokens saved by earlier versions have no mark, so logging out of them behaves exactly as before: the token is only removed.
  • A server without /oauth/revocation (404) or with an outage means a local logout plus the warning.
  • Older CLIs ignore the extra profile key.

Tests

  • internal/commands/minted_token_test.go:
    • a signup token is revoked (once, at the profile's base URL) and removed, and the profile holds the digest, not the token;
    • three cases make no request: a pasted token, a signup token replaced by a login, and a stale mark beside a pasted token;
    • a 500 or 404 still removes the token, warns, and reports revoked: false with the error and no token in it;
    • --all revokes both signup tokens and not the pasted one.
  • Mutation checks:
    • dropping the digest comparison fails the stale-mark case;
    • stubbing out the revocation fails the revoke and failure cases.
  • make lint, go vet ./..., gofmt -l . and go test -race ./internal/commands/ pass, as does go test ./....

Summary by cubic

fizzy auth logout now revokes the write token that fizzy signup created before removing it, so the token no longer stays valid at Fizzy. Tokens handed to fizzy auth login are still only forgotten, never revoked, since they may be in use elsewhere.

  • The CLI records which token signup created by its SHA-256 in the profile (never the token itself); any other save drops that mark, so a pasted token is never revoked.
  • Revocation is best effort and bounded: if Fizzy doesn't confirm it, the credential is still removed locally with a stderr warning printed before cleanup. revoked is true only when every due revocation, including each in --all, went through; any failure reports revoked: false with revoke_error naming the profile. All revocations in one logout share a 20 s deadline. When the credential store can't be read, the fallback config-file token is matched and revoked if it belongs to signup; otherwise an unreadable store counts as a failed revocation, as does a signup token the profile no longer stores, which may still be live.
  • Profiles saved by earlier versions carry no mark, so logging out of them behaves exactly as before.

Written for commit e64b278. Summary will update on new commits.

View guided diff Turn on auto-fix

`fizzy signup` mints a write token ("Fizzy CLI") for the account it
sets up, and `fizzy auth logout` only forgot it: the token stayed valid
at Fizzy until someone revoked it by hand. Logout now revokes that token
at Fizzy's revocation endpoint (RFC 7009, which takes a personal access
token on possession) before removing it, best effort: a failure is
reported on stderr and as revoke_error, and the credential is removed
either way. The result carries `revoked`.

A token given to `fizzy auth login` is only removed, as before. It may be
in use elsewhere, so it isn't the CLI's to revoke. The profile records
which token signup created by its SHA-256, never the token, and any other
save drops the mark. A mark left beside a different token matches
nothing, so a pasted token is never revoked.
Copilot AI balanced review requested due to automatic review settings November 6, 2026 21:13
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T21:50:40.825959Z c35e418 Manual request
🔒 Security Review ✅ Completed 2026-11-06T21:17:29.356815Z f13807e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread internal/commands/auth.go Resolved
Comment thread internal/commands/profile_state.go Resolved
Comment thread internal/commands/auth.go Resolved
Comment thread internal/commands/minted_token_test.go Resolved
Comment thread internal/commands/minted_token_test.go Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

if err := stderrors.Join(cleanupErrors...); err != nil {
return &output.Error{Code: output.CodeAPI, Message: fmt.Sprintf("logout incomplete: %v", err)}

P1 Badge Report revocation failures before returning cleanup errors

If the remote revocation fails and a later local cleanup operation also fails, this early return skips reportMintedTokenRevocations, so the user never receives the warning that the write token remains valid. This is especially problematic when credential/profile deletion succeeded but saving the global config failed: the mark and stored token are already gone, a retry cannot attempt revocation again, and the server-side token is left active without the promised warning; the authLogoutAll cleanup-error path has the same issue.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/commands/auth.go Resolved
Comment thread internal/commands/auth.go Resolved
Comment thread internal/commands/minted_token.go Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Logout can report complete revocation after partial failure and omit warnings that remote tokens remain valid when local cleanup also fails.

2 open issues
What changed in this PR

This PR adds best-effort revocation of signup-created tokens to the CLI’s logout flow, while preserving local-only removal for user-supplied tokens.

Changes:

  • Track signup-created tokens using SHA-256 profile metadata and clear the mark on other credential saves.
  • Revoke matching tokens before logout cleanup, with timeout protection, warnings, and structured results.
  • Add tests for successful revocation, failures, token replacement, and multi-profile logout.

[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

File Description
internal/​commands/​signup.go Marks signup-created credentials as CLI-minted.
internal/​commands/​root.go Allows profile saves to update extra metadata.
internal/​commands/​profile_state.go Records or clears token ownership metadata during saves.
internal/​commands/​minted_token.go Implements digest matching and bounded revocation requests.
internal/​commands/​minted_token_test.go Tests token ownership and logout revocation behavior.
internal/​commands/​auth.go Integrates revocation into logout, reporting, and help text.

Review effort: Balanced

Comment thread internal/commands/auth.go Resolved
Comment thread internal/commands/auth.go Resolved
The revocation warning now prints as each revocation fails, before any
cleanup step can return early. revoked is true only when every due
revocation went through, and revoke_error names each that didn't. A
credential store that can't be read counts as a failed revocation, not an
absent token. All of one logout's revocations share a 20 s deadline, and
tests cover the no-redirect client and restore stderr on failure.
@jeremy

jeremy commented Nov 6, 2026

Copy link
Copy Markdown
Member Author

Fixed — the Codex review finding "Report revocation failures before cleanup errors" (auth.go L160): since 7c5bc47 the warning prints as each revocation fails, before any cleanup error can return.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread internal/commands/minted_token.go Resolved
Comment thread internal/commands/auth.go Resolved
@jeremy

jeremy commented Nov 6, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c35e418fd0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/commands/minted_token.go Resolved
@jeremy

jeremy commented Nov 6, 2026 •

Copy link
Copy Markdown
Member Author

Review threads: 13 resolved (12 fixed, 1 declined with the reasoning in the thread).
Review bodies: 1 finding answered (fixed).

Fixed from a review body:

Declined:

Not reported on the head:

  • Codex last reported on c35e418. It was re-requested once on this PR, and the head is e64b278.

This branch has not been deployed

No deployments
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.

2 participants