Rover Auth Commands

Log in to GraphOS and manage OAuth grants


The rover auth commands authenticate Rover as you, using OAuth, instead of with an API key. Each successful login creates a grant: a credential that lets Rover act on your behalf until it's revoked.

Logging in

auth login

The auth login command opens your default browser so you can authorize Rover with GraphOS:

Text
1rover auth login

Rover opens your browser and prints the authorization URL to stderr, in case the browser doesn't open:

Text
1Opening your browser to authenticate. If it doesn't open automatically, visit this URL: <URL>

Pass --no-open to open the URL yourself. Rover then only prints the URL:

Text
1Visit this URL to authenticate: <URL>

Once you authorize the request, Rover saves the resulting credential to your default profile, or to the profile you name with --profile, and prints Successfully logged in.

Logging in without a browser

If you're on a machine with no browser, such as a remote server, pass --no-browser:

Text
1rover auth login --no-browser

Rover prints a verification URL and a code:

Text
1To finish logging in, visit <URL> and enter the code: <CODE>

Open the URL on any device, enter the code, and approve the request. Rover waits until you do, then prints Successfully logged in. --no-open has no effect with --no-browser.

When your session expires

Rover doesn't refresh an OAuth session automatically. After it expires, commands that use the profile stop authenticating, and rover auth whoami reports:

Text
1error: Your session has expired or is invalid. Run `rover auth login` to reauthenticate.

Run rover auth login again, with the same --profile if you used one.

Checking who you're logged in as

auth whoami

The auth whoami command shows which identity the current profile authenticates as:

Text
1rover auth whoami

What it shows depends on the credential. For an API key or a client-credential pair, Rover looks the credential up in GraphOS, the same way rover config whoami does. With --format json, every field listed for a credential is always present in data, and a value that doesn't apply is null.

CredentialText output rows--format json fields
OAuth login (rover auth login, with or without --no-browser)Name, Email, User ID, Origin, Grant Type, and the masked Access Tokenname, email, user_id, origin, grant_type, and access_token
Personal API key (Key Type is User)Key Type, User ID, Origin, and the masked API Keykey_type, user_id, origin, and api_key. graph_id, graph_title, and grant_type are null.
Graph API key (Key Type is Graph)Key Type, Graph ID, Graph Title, Origin, and the masked API Keykey_type, graph_id, graph_title, origin, and api_key. user_id and grant_type are null.
Client-credential pairKey Type, User ID, Origin, Grant Type, and the masked API Keykey_type, user_id, origin, grant_type, and api_key. graph_id and graph_title are null.

Whenever Rover authenticates with an OAuth credential, whether from a login or by exchanging a client-credential pair, the output includes a Grant Type row:

  • Browser login: you logged in with rover auth login.

  • Device code (--no-browser): you logged in with rover auth login --no-browser.

  • Client credentials: Rover authenticated with APOLLO_CLIENT_ID and APOLLO_CLIENT_SECRET.

  • Unknown — log in again to record it: you logged in with a version of Rover that didn't record how. Run rover auth login again to fix it.

When you authenticate with an API key, there's no grant, so the row is omitted. With --format json, the same value is reported as grant_type: one of "authorization_code", "device_code", "client_credentials", or "unknown", or null for an API key.

For example, when Rover authenticates with a client-credential pair, the text output includes the Grant Type row:

terminal
┌────────────┬────────────────────┐
│ Key Type   ┆ User               │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ User ID    ┆ a-user-id          │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Origin     ┆ $APOLLO_CLIENT_ID  │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Grant Type ┆ Client credentials │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ API Key    ┆ exch********oken   │
└────────────┴────────────────────┘

And the JSON output reports grant_type as "client_credentials":

JSON
1{
2  "json_version": "1",
3  "data": {
4    "key_type": "User",
5    "graph_id": null,
6    "graph_title": null,
7    "user_id": "a-user-id",
8    "origin": "$APOLLO_CLIENT_ID",
9    "grant_type": "client_credentials",
10    "api_key": "exch********oken",
11    "success": true
12  },
13  "error": null
14}

With an API key in APOLLO_KEY, the text output has no Grant Type row, and grant_type is null.

The credential itself is masked. To show it in full, pass --insecure-unmask-key. Use it with care, especially when sharing your screen.

Logging out

auth logout

The auth logout command revokes the current profile's OAuth tokens with GraphOS, then removes them from your machine. Settings stored on the profile with rover config set are kept. A profile left with no settings is removed entirely:

Text
1rover auth logout

Revocation is best effort. If GraphOS can't be reached or rejects the request, Rover warns you and still removes the local credential:

Text
1warning: failed to revoke a token with the OAuth server: <ERROR>. Continuing to remove it locally.

Rover then prints Successfully logged out of profile "<NAME>".

auth logout only works on a profile you logged in to with rover auth login. On a profile that holds a personal API key, it changes nothing and fails:

Text
1error: profile "<NAME>" isn't logged in via `rover auth login`
2        If you're using a Personal API Key, run `rover config delete <NAME>` instead.

On a profile that has settings but no credential, it fails with E055, and with no profile of that name, with E021.

Revoking a user's grants

auth grants revoke

When someone leaves your organization, or a credential may be compromised, an organization admin can revoke every grant a user holds with one command:

Text
1rover auth grants revoke --org <ORGANIZATION_ID> --user <USER_ID> --all

This revokes the user's grants under:

  • Rover's own OAuth client. That covers every rover auth login the user has done.

  • Every client-credential pair registered in the organization.

--org, --user, and --all are all required. There's no way to revoke every grant in an organization at once.

caution
Revoking doesn't end everything:
  • Access tokens the user already holds keep working until they expire.
  • The user can log in again. To stop that, remove them from the organization.
  • Studio web sessions aren't affected.
  • Pairs registered in other organizations aren't affected.

Before revoking anything, Rover lists every pair in the organization. If it can't list them all, it revokes nothing and fails. It then shows each OAuth client it revokes under and asks you to confirm. Pass --confirm to skip the prompt.

note
If Rover has no terminal to ask on, for example in CI or with --format json, it doesn't wait for an answer. Without --confirm, it revokes nothing and fails with error E062.

If the user isn't a current member of the organization, Rover warns you and revokes their grants anyway. A departing user is often removed from the organization before their grants are revoked.

When revocation fails under some clients

Rover tries every client, even after one fails, and reports the outcome under each. If any fail, the command exits with error E063 and names each client to retry, with the error GraphOS returns. Run the same command again to retry. Revoking under a client where the user no longer holds a grant succeeds, so a retry only changes the clients that failed.

In text output, Rover reports the outcome under each client in a table:

terminal
┌────────────────┬───────────────────┬─────────┐
│ Client         ┆ Client ID         ┆ Outcome │
╞════════════════╪═══════════════════╪═════════╡
│ Rover          ┆ <ROVER_CLIENT_ID> ┆ revoked │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ ci-deploy      ┆ c_8f2a            ┆ revoked │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ nightly-checks ┆ c_91be            ┆ failed  │
└────────────────┴───────────────────┴─────────┘

With --format json, every client is reported in data.clients, so a script can see which ones failed without parsing the error message:

JSON
1{
2  "json_version": "1",
3  "data": {
4    "organization_id": "acme",
5    "user_id": "user-123",
6    "user_is_member": true,
7    "clients": [
8      { "client_id": "<ROVER_CLIENT_ID>", "name": "Rover", "kind": "rover", "outcome": "revoked", "error": null },
9      { "client_id": "c_8f2a", "name": "ci-deploy", "kind": "client_credentials", "outcome": "revoked", "error": null },
10      { "client_id": "c_91be", "name": "nightly-checks", "kind": "client_credentials", "outcome": "failed", "error": "<the error GraphOS returned>" }
11    ],
12    "cancelled": false,
13    "success": false
14  },
15  "error": {
16    "message": "Revocation failed under 1 of 3 OAuth clients.",
17    "code": "E063"
18  }
19}

<ROVER_CLIENT_ID> stands for the client ID rover auth login uses: Rover's built-in client, or APOLLO_OAUTH_CLIENT_ID if you set it. user_is_member is null when Rover couldn't determine whether the user is a member.

note
Revoking grants across an organization requires the organization's grant-management permission. Without it, Rover fails with error E053. Run rover explain <CODE> for details on any error code.

rover auth grants revoke acts on an organization's grants. Listing grants, and revoking a single grant, aren't supported yet.