> ## Documentation Index
> Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Authentication

> Sign in to the Photon CLI with a device code and manage your stored session.

Photon CLI signs you in with the OAuth 2.0 device authorization grant
([RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628)). You approve the
login in a browser, and the CLI stores the resulting tokens in your operating
system's credential manager.

```sh theme={null}
photon login
photon whoami
photon auth status
photon logout
```

For non-interactive environments such as CI, use an
[Account Service Key](/docs/beta/cli/service-keys) instead.

## Sign in

<Steps>
  <Step title="Run `photon login`">
    The CLI first checks that secure credential storage is available. If it is
    not, the login stops before it contacts Photon.
  </Step>

  <Step title="Approve in the browser">
    The CLI prints a verification URL and a user code, then opens your browser
    at a link that already contains the code. Pass `--no-browser` to print the
    URL and enter the code yourself.
  </Step>

  <Step title="Wait for approval">
    The CLI polls at the interval Photon selects and backs off when asked to.
    A spinner shows progress in an interactive terminal, and is omitted in
    `--json` mode.
  </Step>

  <Step title="Credentials are stored">
    Only after you approve the login does the CLI write the access token and
    rotating refresh token to secure storage.
  </Step>
</Steps>

Denial, expiry, and protocol errors end the login immediately. Pressing
<kbd>Ctrl-C</kbd> aborts the wait, stores nothing, and exits with code `130`.

Useful variants:

```sh theme={null}
photon login --no-browser        # print the URL instead of opening a browser
photon login --force             # replace a healthy session
photon login --insecure-storage  # store credentials in a file, not a keychain
```

`photon login` is a no-op when your existing session is already healthy. With
`--force`, the old session stays usable throughout the new device flow and is
replaced only once the new credential is stored.

## Where credentials are stored

Secure storage is mandatory by default:

| Platform | Credential store |
| - | - |
| macOS | Keychain |
| Windows | Credential Manager |
| Linux | Secret Service through `secret-tool` |

On Linux, install the libsecret command-line tools and make sure a Secret
Service keyring is running and unlocked. The CLI never silently falls back to a
plaintext file.

`--insecure-storage` explicitly opts into a per-user `credentials.json` instead.
On POSIX systems the CLI creates it with mode `0600` inside a `0700` directory,
and writes it atomically so an interrupted command cannot leave a partial
credential behind.

Non-secret metadata — the API origin, which storage backend is in use, your
cached identity, and timestamps — lives in `auth.json` alongside it:

| Platform | Configuration directory |
| - | - |
| Linux | `${XDG_CONFIG_HOME:-~/.config}/photon` |
| macOS | `~/Library/Preferences/photon` |
| Windows | `%APPDATA%\photon\Config` |

<Warning>
  If the CLI finds an unknown or malformed credential schema, it refuses to
  overwrite it. `photon auth status` then reports storage as `unavailable`, and
  `photon logout --force` removes the local files it recognizes while warning
  that an entry may remain in your secure store.
</Warning>

## Refresh and concurrent commands

You do not need to refresh anything by hand. The CLI renews the access token
60 seconds before it expires, and always reads your identity and authorization
from Photon rather than trusting the token's contents.

You can run several `photon` commands at once. They coordinate through a lock,
so only one process performs the exchange and the others pick up the rotated
tokens. A transient refresh failure leaves your credentials intact and asks you
to retry; only a rejected refresh token deletes them and requires a new login.

## Session commands

| Command | Behavior |
| - | - |
| `photon login` | Validates the current session and does nothing if it is healthy. |
| `photon whoami` | Returns your canonical identity from Photon, in compact form. |
| `photon account view` | Returns the complete account resource. |
| `photon auth status` | Reports `authenticated`, `not_authenticated`, or `unavailable`. |
| `photon logout` | Deletes local credentials, and succeeds even if you are not signed in. |

`photon logout` is local-only. Photon's authentication service has no
revocation endpoint, so signing out does not revoke the remote session.

## Limits

The stored schema supports one staging account. Production origins, named
profiles, token import and export, and remote revocation are out of scope for
the beta.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.