Skip to content

feat(cli): mergify auth login, logout and status - #1806

Draft
sileht wants to merge 1 commit into
devs/sileht/mrgfy-8703-cli-auth-commands/device-authz-grant-client-side--c7a625b9from
devs/sileht/mrgfy-8703-cli-auth-commands/mergify-auth-login-logout-status--b0b7d166
Draft

feat(cli): mergify auth login, logout and status#1806
sileht wants to merge 1 commit into
devs/sileht/mrgfy-8703-cli-auth-commands/device-authz-grant-client-side--c7a625b9from
devs/sileht/mrgfy-8703-cli-auth-commands/mergify-auth-login-logout-status--b0b7d166

Conversation

@sileht

@sileht sileht commented Sep 4, 2026

Copy link
Copy Markdown
Member

The three commands that give a machine a Mergify credential, take it
away, and say which one it holds.

login prints a URL and a code and waits. The credential lands in the
OS keychain, or in a 0600 file when the machine has none, and the
command says which -- a user who has to reason about where their secret
is should not have to guess.

logout revokes server-side before it deletes locally, because the
server's copy is the one that matters and a token whose only trace was
the file we just deleted can no longer be revoked from here at all. If
the revocation fails the local copy still goes: a logout that left the
credential in place because the network blinked would have done nothing
at all. The command says so, and names where to finish the job.

status asks the API rather than trusting the disk. A token revoked
from the dashboard is still on the machine and still carries a
year-away expiry, so a status that read only the local copy would
report a dead credential as live.

Three deliberate calls:

  • No --json. The surface is exactly login|logout|status [--api-url URL], which is what the docs are being written against
    right now.
  • No browser is opened. The device grant exists because the CLI runs
    where there is no browser to open -- over SSH, in a container -- and a
    command that only works when there is one would be a different
    feature.
  • A deployment without GET /v1/user still works. Self-hosted
    installs upgrade on their own schedule, so a 404 there means "cannot
    name the account", not "login failed" -- login stores the credential
    and status reports it, both saying what they could not check.

login revokes the credential it replaces, and the one it minted but
could not store. Neither is reachable from this machine afterwards,
and both stay live on the server for a year -- leaking one per login
walks the user into the twenty-token cap that only the dashboard can
clear.

auth status exits 8 when there is no usable credential, which is the
code every Mergify command has always returned for that condition. The
published description of that code said "configuration file", which was
never true of a missing token; it now says configuration or
credentials.

The credential is stored but nothing else reads it yet; the next commit
puts it in the resolution chain. No message here claims otherwise.

Fixes MRGFY-8703

Depends-On: #1805

@sileht

sileht commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

This pull request is part of a Mergify stack:

# Pull Request Link
1 refactor(core): split Mergify and GitHub token resolution #1802
2 feat(core): store the Mergify credential in the OS keychain #1803
3 feat(core): let a caller read an endpoint's rejection body #1804
4 feat(auth): the device authorization grant, client side #1805
5 feat(cli): mergify auth login, logout and status #1806 👈
6 feat(core): use the stored credential, deprecate GITHUB_TOKEN #1807
7 fix(core): never send a Mergify user token to GitHub #1808

@mergify

mergify Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 3 of 7 protections blocking · waiting on 👀 reviews and ⛓️ dependency

Protection Waiting on
🔴 ⛓️ Depends-On Requirements ⛓️ dependency
🔴 👀 Review Requirements 👀 reviews
🔴 🔎 Reviews 👀 reviews
🟢 🤖 Continuous Integration
🟢 Enforce conventional commit
🟢 📕 PR description
🟢 🚦 Auto-queue

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by>=2
This rule is failing.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
This rule is failing.
  • #review-requested = 0
  • #changes-requested-reviews-by = 0
  • #review-threads-unresolved = 0

Show 4 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success=ci-gate

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

@mergify
mergify Bot requested a review from a team September 4, 2026 23:26
The three commands that give a machine a Mergify credential, take it
away, and say which one it holds.

`login` prints a URL and a code and waits. The credential lands in the
OS keychain, or in a `0600` file when the machine has none, and the
command says which -- a user who has to reason about where their secret
is should not have to guess.

`logout` revokes server-side before it deletes locally, because the
server's copy is the one that matters and a token whose only trace was
the file we just deleted can no longer be revoked from here at all. If
the revocation fails the local copy still goes: a `logout` that left the
credential in place because the network blinked would have done nothing
at all. The command says so, and names where to finish the job.

`status` asks the API rather than trusting the disk. A token revoked
from the dashboard is still on the machine and still carries a
year-away expiry, so a `status` that read only the local copy would
report a dead credential as live.

Three deliberate calls:

- **No `--json`.** The surface is exactly `login|logout|status
  [--api-url URL]`, which is what the docs are being written against
  right now.
- **No browser is opened.** The device grant exists because the CLI runs
  where there is no browser to open -- over SSH, in a container -- and a
  command that only works when there is one would be a different
  feature.
- **A deployment without `GET /v1/user` still works.** Self-hosted
  installs upgrade on their own schedule, so a 404 there means "cannot
  name the account", not "login failed" -- `login` stores the credential
  and `status` reports it, both saying what they could not check.

`login` revokes the credential it replaces, and the one it minted but
could not store. Neither is reachable from this machine afterwards,
and both stay live on the server for a year -- leaking one per login
walks the user into the twenty-token cap that only the dashboard can
clear.

`auth status` exits 8 when there is no usable credential, which is the
code every Mergify command has always returned for that condition. The
published description of that code said "configuration file", which was
never true of a missing token; it now says configuration *or*
credentials.

The credential is stored but nothing else reads it yet; the next commit
puts it in the resolution chain. No message here claims otherwise.

Fixes MRGFY-8703

Change-Id: Ib0b7d16696fa41fc733f2d0fa6ef34246ad8eeb9
@sileht
sileht force-pushed the devs/sileht/mrgfy-8703-cli-auth-commands/mergify-auth-login-logout-status--b0b7d166 branch from 58321f1 to 4b9647a Compare September 4, 2026 23:40
@sileht
sileht force-pushed the devs/sileht/mrgfy-8703-cli-auth-commands/device-authz-grant-client-side--c7a625b9 branch from bc88a36 to 048166f Compare September 4, 2026 23:40
@sileht

sileht commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Revision history

# Type Changes Reason Date
1 initial 58321f1 2026-09-04 23:40 UTC
2 rebase 58321f1 → 4b9647a (rebase only) 2026-09-04 23:40 UTC

@mergify
mergify Bot had a problem deploying to Mergify Merge Protections September 4, 2026 23:41 Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant