Auth
The agent’s /api/* and /ws/* routes are guarded by an operator gate. The gate is fail-safe: it is enabled only when a GitHub OAuth client id/secret and a master key are configured. Otherwise the agent behaves as before (open) and logs a one-time warning.
The gate is on when all of these are true:
auth_github_client_idis set (config).STEELFRAME_GITHUB_CLIENT_SECRETis set (environment).STEELFRAME_MASTER_KEYis set (environment).auth_enabledis notfalse/0.
Access rule: the GitHub login must be in auth_allowed_users (comma/newline separated config) or be a member of auth_github_org (config, default chipcolate).
Routes
Section titled “Routes”These are always mounted; login reports 404 when auth is not configured.
| Method | Path | Purpose |
|---|---|---|
GET | /api/auth/login | Redirect to GitHub OAuth |
GET | /api/auth/callback | Exchange the code, issue a session |
GET | /api/auth/logout | Clear the session cookie |
GET | /api/auth/me | Return the verified login or 401 |
Web GUI — session cookie
Section titled “Web GUI — session cookie”Sign in with GitHub. The callback sets a signed sf_session cookie:
HttpOnly; Secure; SameSite=Lax; Max-Age=14 daysThe session token is self-contained: v1.<user-b64url>.<expiry-unix>.<HMAC-SHA256>, signed with the master key. There is no server-side session store. The OAuth state carries a nonce and the redirect target in a short-lived cookie, and redirect targets are restricted to same-origin paths.
Every request is verified from the cookie (or an Authorization: Bearer). On success the middleware overwrites X-Auth-User with the verified login, so handlers and audit logs cannot see a spoofed identity.
Desktop GUI — token paste
Section titled “Desktop GUI — token paste”Desktop has no cookie session to recover in-app. The re-authentication gate opens:
<agent>/api/auth/login?desktop=1&rd=/The callback renders the session token in the browser as a page for copy-paste. Paste it into the app, which sends it as Authorization: Bearer and saves it to the project registry (projects.toml).
TUI — bearer token
Section titled “TUI — bearer token”The TUI reads each project’s token from ~/.config/steelframe/projects.toml and sends it as Authorization: Bearer. It also sends X-Auth-User on every request so GitHub issue footers name the real operator.
The agent also accepts a pre-shared automation token from STEELFRAME_TUI_TOKEN. When it matches, the request authenticates as the STEELFRAME_OPERATOR value (or automation).
Create a remote token on the host:
ssh root@HOST cat /root/steelframe-tui.token > /tmp/steelframe-tui.tokensteelframe config \ --name makolate-stack \ --url https://makolate.steelframe.chipcolate.com \ --token-file /tmp/steelframe-tui.token \ --operator your-github-loginX-Auth-User and the master key
Section titled “X-Auth-User and the master key”Resolution order for the operator identity when auth is disabled:
X-Auth-UserX-Forwarded-UserSTEELFRAME_OPERATORunknown
When auth is enabled, only the verified login survives; client-supplied identity headers are replaced.
STEELFRAME_MASTER_KEY is the HMAC key for session tokens and the source for credential encryption. Keep the same value for the life of the VM; rotating it invalidates sessions and makes existing credentials undecryptable.
Gotchas
Section titled “Gotchas”- When the gate is disabled, an unauthenticated request succeeds and the actor is
unknown. Set the identity headers or auth to get correct issue footers. 401responses carry{ "error": "unauthenticated", "login_url": "/api/auth/login" }.- Session tokens expire after 14 days; the Desktop app prompts for a fresh paste when an agent rejects the saved token.
- The agent-native OAuth App callback is
https://<HOST>/api/auth/callback. The infra oauth2-proxy path uses a separate GitHub OAuth App with callbackhttps://<HOST>/oauth2/callback(seeinfra/secrets.mk.example).