Authentication

Device code flow (RFC 8628), API tokens, token scopes, and web OAuth on mog.md.

mog uses two authentication systems: the web app uses OAuth (GitHub/Google) via NextAuth, while the CLI and API use a device code flow designed for headless environments and autonomous agents.

Device code flow (CLI & API)

The device code flow follows RFC 8628. It lets a CLI or agent authenticate without ever opening a browser on the host machine — ideal for CI, Docker containers, and agent runners.

How it works

  1. The CLI calls POST /v1/auth/device/start — no credentials needed. The API returns a deviceCode (used internally), a short userCode (shown to the user), a verificationUri, and a polling interval.
  2. The CLI displays the code and URL to the user. It tries to open the browser automatically, but this is best-effort (it's fine if the environment is headless).
  3. The user opens mog.md/device in any browser, signs in with GitHub or Google, and enters the code.
  4. The CLI polls POST /v1/auth/device/poll every interval seconds. When the user approves, the poll response includes a Bearer token.
  5. The CLI stores the token locally and uses it for all future API requests.

Flow diagram

CLI                          API                        Browser
 |                             |                              |
 |-- POST /auth/device/start ->|                              |
 |<-- { deviceCode, userCode } |                              |
 |                             |                              |
 | (display userCode to user)  |                              |
 |                             |                              |
 |-- poll /auth/device/poll -->|      user visits /device     |
 |<-- { status: pending }      |<-- POST /auth/device/approve |
 |                             |    { userCode }              |
 |-- poll /auth/device/poll -->|                              |
 |<-- { status: approved,      |                              |
 |      token: "mog_..." }     |                              |

Code expiry

Device codes expire after 15 minutes (expiresIn: 900). If the user doesn't approve in time, the poll returns { "status": "expired" } and the CLI exits with an error. Run mog auth again to start a new flow.

API tokens

Tokens returned by the device flow are API tokens. They are stored as SHA-256 hashes in the database — the plaintext token is only returned once, at issuance time. Store it securely.

Token format

Tokens come in two forms:

  • Signed JWT-like tokens: Created by the device flow. Verified by HMAC using the JWT_SECRET.
  • API tokens: Created from the dashboard. Stored hashed in the database and looked up on each request.

Using a token

Authorization: Bearer mog_your_token_here

All protected API endpoints accept this header.

Token scopes

Tokens have one or more scopes that limit what they can do. The device flow issues tokens with all scopes by default; tokens created from the dashboard can be restricted.

ScopeGrants access to
readGET /v1/users/me, GET /v1/entitlements, POST /v1/listings/.../reviews
purchasePOST /v1/purchases
downloadPOST /v1/downloads
sellAll /v1/vendor/* endpoints

For an autonomous agent that only needs to install packages, you can restrict the token to read, purchase, and download scopes — preventing it from uploading new releases or modifying vendor settings even if compromised.

Revoking a token

# Via CLI
mog auth --logout
 
# Via API
POST /v1/auth/token/revoke
Authorization: Bearer <token>
 { "ok": true }

Revocation is immediate. Any subsequent request with the revoked token returns HTTP 401.

Spend policies on tokens

API tokens can be attached to a spend policy that limits autonomous purchasing. This is the recommended setup for agent tokens:

  1. Create a spend policy in your dashboard
  2. Create or update an API token, attaching the policy ID
  3. Give the token to the agent

The policy is enforced server-side on every purchase request made with that token, regardless of what the client sends.

Web app authentication

The web app at mog.md uses Auth.js v5 (NextAuth) with OAuth providers:

  • GitHub: OAuth app, callback URL: https://mog.md/api/auth/callback/github
  • Google: OAuth client, callback URL: https://mog.md/api/auth/callback/google

Web sessions are separate from API tokens. When you sign in to the web app, the web app internally issues an API token on your behalf for browser-based operations (purchasing, seller dashboard). This token is never exposed to the browser.

The device authorization page

The CLI sends users to mog.md/device. On this page, users:

  1. Sign in with GitHub or Google (if not already signed in)
  2. Enter the 8-character code shown by the CLI
  3. Review the scopes being requested
  4. Click Approve

The web app then calls POST /v1/auth/device/approve with the user code. The CLI's next poll returns the token.

Authentication in automation

For CI pipelines and non-interactive automation, generate a token from the dashboard and set it as an environment variable. You can then skip the interactive device flow:

# Set token via environment variable
export MOG_TOKEN=mog_your_token_here
 
# The CLI reads MOG_TOKEN before checking the credentials file
mog install acme/some-skill --auto-buy

Always attach a spend policy to automation tokens to limit the blast radius if a token is leaked.

On this page