ADR-0010: grm CLI uses OAuth 2.0 Device Flow with long-lived API key storage

Status

Accepted

Tags

cli, grm, oauth2, device-flow, api-key, authentication, better-auth

Decision

grm auth login uses the OAuth 2.0 Device Authorization Grant (RFC 8628). The CLI requests a device code, opens the browser to the admin panel’s /device page where the user explicitly approves, then polls for an access token. Once received, the access token is immediately exchanged for a long-lived API key via Better Auth’s apiKey plugin. Only the API key is persisted to ~/.config/grm/config.json. The access token is discarded.

Why

The CLI must authenticate on behalf of developers and AI agents — including cases where no human is present after initial login. Alternatives rejected:
  • Username/password flags — requires typing credentials into the terminal, incompatible with SSO/OAuth, stores a password at rest.
  • Session cookie — browser-scoped, cannot be portably persisted across CLI invocations.
  • Store the access token — access tokens are short-lived; agents would need to re-authenticate mid-task with no human present to approve.
Storing an API key means every subsequent CLI invocation sends x-api-key with no expiry concern, and the key can be named and revoked independently per device.

Flow

Device approval page

The /device page in the admin panel requires an active session and shows explicit Approve and Deny buttons — it does not auto-approve on mount. Auto-approving silently on load would allow a stolen user_code link to approve a device without the user’s awareness.

Rules for agents

  • Never store the access token to disk — exchange it for an API key immediately and discard
  • The device page must require a confirmed session before rendering Approve/Deny
  • grm auth whoami authenticates via x-api-key header, not Bearer token
  • Config file permissions must be 0600 (owner read/write only)