Authentication
There are no API keys and no bearer tokens. A request is authenticated by the browser session that signing in creates.
A session, not a key
Sign-in is OIDC with Google or GitHub. It sets a cookie named
promptpotter_session: an opaque server-side id, HttpOnly,
Secure on https, SameSite=Lax. A request without a valid session returns
401 with the message
sign-in required.
Local installs
The API is open, with no session, when PROMPTPOTTER_AUTH=off,
or when ENVIRONMENT=development (the default) and no sign-in
provider is configured. That is the mode a local install starts in.
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /auth/login/{provider} | Start sign-in with a provider. |
| GET | /auth/callback/{provider} | The provider’s redirect target. Sets the session cookie. |
| POST | /auth/logout | End the session. |
| GET | /auth/me | The caller’s identity envelope. |
| GET | /auth/quota-status | The caller’s live quota: usage, and the resolved ceilings. |
| GET | /auth/user-settings | The current user’s preferences. |
| PATCH | /auth/user-settings | Persist a preference change for the current user. |
| POST | /auth/accept-terms | Record the current user’s acceptance of the Terms, server-stamped. |
| GET | /auth/activity | Time-bucketed spend, requests and tokens over a window. |
/auth/activity takes a window query, for example ?window=1d.
GET /auth/me
The response carries these fields:
- user_id
- tenant_id
- issuer
- name
- provider
- connected_accounts
- available_providers
- capabilities
- access_state
- terms_version
- terms_accepted_version
The app’s consent gate compares terms_accepted_version
with terms_version.
In the repo
- ADR-0002, identity ↗
- Why the cookie is opaque.
- Access model ↗
- Who gets in, and what bounds an account.