OAuth device flow explained: how CLIs and AI agents approve access
You’ve seen it on a smart TV: “Go to example.com/device and enter code ABCD-1234”. That’s the OAuth device authorization flow, RFC 8628 — and it’s the right way for headless tools, CLIs, and AI agents to get OAuth tokens. Here’s how it works and why it matters for agent security.
The problem with OAuth on a headless machine
OAuth’s normal web flow needs a browser redirect: authorize → the provider
redirects to http://localhost:8976/callback?code=.... On a headless server
or inside an agent session there’s no browser to redirect to — and no user
watching the address bar.
The workaround people fall into is worse: paste a personal access token into a config file, or run a long-lived refresh token into the environment where the agent can read it. Both put credentials where agents can exfiltrate them.
How the device flow works
RFC 8628 splits authorization into two steps that don’t need to happen on the same device:
- The CLI asks the provider for a device code and gets back a verification URL + a short user code.
- The CLI prints “open this URL, enter ABCD-1234” — and starts polling the provider for approval.
- The user opens the URL on any device — phone, laptop, anywhere — and approves. No browser on the server needed.
- The CLI’s poll succeeds, and the provider returns tokens.
The tokens land on the machine that requested them, in the process that requested them — not in a browser, not in a shared log.
Why it fits agents
For AI agents, the device flow has a structural advantage: the approval happens outside the agent entirely. The agent runs the login command, prints the URL, and the human approves on their own device. The tokens are stored by the credential layer, and the agent never handles them.
That’s the same principle as the rest of agent credential hygiene — the agent is an untrusted caller, so credentials should be resolved and refreshed outside its reach.
Token handling done right
Getting tokens is step one; keeping them safe is step two:
- Store the entry compactly. The OAuth entry lives in the credential store as a single-line JSON record — one entry, resolved like any other secret.
- Refresh without exposure. Access tokens expire; the broker refreshes on expiry, and the new value is never printed to output the agent can capture.
- Rotate refresh tokens. Refresh tokens are single-use in this design — rotated on every refresh, so a leaked one is already dead.
- Report state.
statustells youvalid/expired/reauth_required, so automation can detect a revoked token (invalid_grant) and ask the human to re-approve instead of failing silently.
The audit trail
Every resolution and refresh lands in an append-only audit log. You can answer “which key was accessed, when, and by what” — including OAuth entries, which most setups can’t audit at all because the tokens live in browser profiles and config files.
trustless implements the device
flow for Google and Lark providers (trustless oauth login google api/google), with automatic refresh, single-use rotation, and status
reporting — documented in the command reference.
The device flow is one of those rare security mechanisms that’s also more convenient: no browser juggling on the server, no callback URL gymnastics, and a human approval step that’s exactly where it should be.