Skip to main content

packages/auth — recreator auth

Device-flow sign-in for the CLI, and the one file that holds the MCP token.

recreator auth login → device code → browser: email + OTP → approve → rcr_ token at ~/.recreator/token

Why the device flow

OAuth 2.0 Device Authorization Grant (RFC 8628), the same model as gh auth login. Chosen over a localhost-callback server because it needs no free port and no reachable loopback — so it works over SSH and inside a container, which is where an agent toolkit actually runs.

The two hops

/device/token returns a Better Auth session token, not an API key. Sessions expire and are cookie-cache bound; the MCP server authenticates with an @better-auth/api-key value. So login is two requests:

  1. POST /api/auth/device/codedevice_code, user_code, verification_uri
  2. poll POST /api/auth/device/token → session token on approval
  3. POST /api/auth/api-key/create with that session → the raw rcr_ key, returned exactly once (the server stores only a SHA-256 digest)

Only the rcr_ key is written to disk. The session token is discarded.

Polling rules that are not optional

Encoded in poll_for_token, and the reason that function takes an injectable sleep and monotonic:

  • Honour the server's interval (5s as configured).
  • slow_down adds 5s and keeps going — it is not a failure.
  • authorization_pending keeps going.
  • access_denied / expired_token stop with an actionable message.
  • Stop at expires_in. The deadline is checked before sleeping, so the loop never spends an interval to learn what it already knows.

The token file

~/.recreator/token, mode 0600, in a 0700 directory, created with the final mode rather than chmod-ed afterwards — an umask-widened file would be world-readable for the window in between.

Login refuses to overwrite an existing token without --force, matching the project's convention for destructive acts.

~/.recreator/ is shared with unrelated secrets (registry-token, env.sh, resend-api-key). This package reads and writes the token entry and nothing else. RECREATOR_TOKEN_FILE overrides the path, which is how tests stay off a real credential.

Client identity

client_id is recreator-cli, which must appear in the portal's DEVICE_CLIENT_IDS allowlist (apps/web/src/lib/auth.ts). The allowlist is load-bearing: without it the plugin accepts any client_id, and a device code could be minted under an attacker-chosen identity.

Layout

storage.py   the token file: permissions, overwrite refusal, masking
device.py    RFC 8628 protocol + the polling state machine. No I/O beyond HTTP.
session.py   session → rcr_ key exchange, and identity lookup for `status`
login.py     order of operations, printed output, exit codes

device.py talks to a Transport protocol, so the state machine is tested with a scripted transport and a fake clock — no network, no real sleeping.

Commands

recreator auth login                 # device flow, opens a browser
recreator auth login --no-browser    # print the URL instead (SSH, containers)
recreator auth login --force         # replace an existing token
recreator auth status                # masked token + portal validation
recreator auth status --offline      # skip the portal round trip
recreator auth logout                # delete the token

--base-url points any of these at a preview deployment instead of production.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

recreator_auth-0.1.1.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

recreator_auth-0.1.1-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file recreator_auth-0.1.1.tar.gz.

File metadata

  • Download URL: recreator_auth-0.1.1.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for recreator_auth-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8a3bef2e8e8b6deccc9edae95d5aa8c1b8d09ec99a565750a5ee7cdd30a37b95
MD5 299481290dc692f1172b27805ad53dde
BLAKE2b-256 d9d454a3e97956cd1335d203fe242070a81a9f0ba90f37733495164e30da3cbc

See more details on using hashes here.

File details

Details for the file recreator_auth-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: recreator_auth-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for recreator_auth-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c3fba684b55c7312c61255ab7629722dcd1881776caef96ba222f9b150969020
MD5 3600bc13f44542bb246f96414ec3c40e
BLAKE2b-256 72c663b5d85c3425cf1e1e9c75eac9e87c5cf9645b4f4edb1e27ccf5929c706e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

This release

0.1.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page