Atom

Authentication

Token types, credential management, and how authentication works in Atom.

Atom supports JWTs, API keys, scoped access tokens, and mTLS certificates.

JWTs, API keys, and scoped access tokens are passed as Bearer tokens in the Authorization header:

Authorization: Bearer <token>
Token typeFormatUse case
JWTeyJ...Short-lived (default 1h), returned by /auth/login
API keyatom_...Long-lived, provisioned for an entity, optional expiry
Scoped access tokenatom_...Self-service CLI/API token capped by a permission ceiling

Certificates are used during mTLS. Runtime services resolve certificate identity through Atom gRPC.

Public endpoints

The following endpoints do not require authentication:

GET  /health
GET  /auth/public-config
POST /auth/login
POST /auth/signup   # only when ATOM_SELF_REGISTRATION_ENABLED=true
GET  /auth/email/verify
POST /auth/email/resend
GET  /auth/oauth/:provider/start
GET  /auth/oauth/:provider/callback
POST /auth/oauth/exchange
GET  /.well-known/jwks.json
GET  /certs/trust-bundle.pem
GET  /certs/issuers/{issuer_id}/crl
POST /certs/issuers/{issuer_id}/ocsp

All other endpoints require a valid Bearer token. Public signup creates a global human entity with tenant_id = NULL; tenants are assigned later through admin, invitation, or membership workflows. Signup does not create tenants or grant platform privileges.

Sections

Google, GitHub and Apple login

Set complete ATOM_GOOGLE_CLIENT_ID / ATOM_GOOGLE_CLIENT_SECRET, ATOM_GITHUB_CLIENT_ID / ATOM_GITHUB_CLIENT_SECRET, or ATOM_APPLE_CLIENT_ID / ATOM_APPLE_CLIENT_SECRET pairs. Blank placeholders leave a provider disabled; partial pairs and duplicate provider names refuse startup. Existing ATOM_OIDC_PROVIDERS JSON configuration remains supported. ATOM_SELF_REGISTRATION_ENABLED must be enabled to start social authentication.

Register ${ATOM_PUBLIC_BASE_URL}/auth/oauth/google/callback, ${ATOM_PUBLIC_BASE_URL}/auth/oauth/github/callback and ${ATOM_PUBLIC_BASE_URL}/auth/oauth/apple/callback with the corresponding provider. Set ATOM_OAUTH_SUCCESS_REDIRECT and ATOM_OAUTH_ERROR_REDIRECT to the frontend callback. For Atomic both are its public /auth/callback URL.

Google uses OIDC discovery, PKCE and nonce verification. GitHub uses its OAuth code exchange with PKCE, then reads the authenticated numeric user ID and a verified primary email from /user and /user/emails. Provider access tokens are used only during the callback and are not stored.

Apple uses OIDC signature, audience, issuer and nonce verification and a form-urlencoded POST callback (POST /auth/oauth/apple/callback). That callback returns HTTP 303 so the frontend receives a GET. Configure an Apple Services ID and a generated ES256 client-secret JWT, signed with the developer team's key; rotate the JWT before expiry (Apple allows at most six months). Client credentials are sent in the token request body. Apple requires a public HTTPS callback. See Apple setup.

A frontend may add a random client_state to the start request, keep it in its browser session and submit the same value with {code, client_state} to POST /auth/oauth/exchange. Atom persists the binding through provider state and the single-use exchange code, rejecting missing or mismatched values before consuming the code. This prevents an attacker substituting their own code into another browser's login. Existing clients that omit client_state at both ends continue to work. The exchange response preserves the usual login fields and adds nullable email, taken from the provider's verified identity.

A new provider can link by email only to an already verified account email; unverified password accounts must verify their email first. Repeated provider logins use the stable provider subject and active-entity checks.

On this page