TILLAUTH · FLOWS

Sign in with TillAuth.

OIDC

TillAuth is an OpenID Connect provider. Your users already have accounts in a TillAuth app — now your own consoles, dashboards and back-end services can sign them in with the standard authorization code flow. Any OIDC-compliant client library works; no TillAuth SDK required.

01Discovery

Endpoints

Point your OIDC client at the discovery document and it configures itself. The issuer is https://auth.tilldev.dev.

https://auth.tilldev.dev/.well-known/openid-configuration
EndpointURL
authorization_endpointhttps://tilldev.dev/oidc/authorize
token_endpointhttps://auth.tilldev.dev/v1/oidc/token
userinfo_endpointhttps://auth.tilldev.dev/v1/oidc/userinfo
end_session_endpointhttps://auth.tilldev.dev/v1/oidc/logout
jwks_urihttps://auth.tilldev.dev/.well-known/jwks.json

Supported: code response type, authorization_code and refresh_token grants, EdDSA id_token signatures, PKCE with S256.

02Set up

Register a client

Each relying party (a console, a service) is registered against the TillAuth app whose users it signs in. Register one with the CLI:

# confidential client (has a back end that can keep a secret) tilldev auth clients <app> create "Ops Console" \ --redirect https://ops.acme.com/auth/callback \ --scopes openid,email,profile # → prints client_id and client_secret (the secret is shown once)

For a single-page app or native client that can't hold a secret, add --public — it authenticates with PKCE instead of a secret. List and remove clients with tilldev auth clients <app> and tilldev auth clients <app> rm <client_id>.

SettingNotes
redirect_urisExact-match allow-list. A redirect must equal a registered URI character-for-character — no wildcards.
scopesSubset of openid email profile offline_access. openid is always included.
client_secretShown once at creation for confidential clients. Store it in your app config; rotate by creating a new client.
client typeconfidential (back-end) or public (PKCE-only, no secret).
03Sign-in

The authorization code flow

PKCE is required. A typical flow:

  1. Your client generates a code_verifier + code_challenge (S256) and redirects the browser to the authorization endpoint with client_id, redirect_uri, scope, state, nonce, and the challenge.
  2. The user signs in on the TillAuth-hosted page (their password, passkey, MFA — whatever the app allows) and approves the requested scopes.
  3. TillAuth redirects back to your redirect_uri with a single-use code and your state.
  4. Your back end exchanges the code at the token endpoint (with the code_verifier, and the client secret for confidential clients) for an id_token, access_token, and refresh_token.
POST https://auth.tilldev.dev/v1/oidc/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=<code> &redirect_uri=https://ops.acme.com/auth/callback &code_verifier=<verifier> &client_id=<client_id> &client_secret=<client_secret> # confidential clients only
Note
Validate the id_token the way any OIDC library does: signature against the JWKS, iss equals the issuer, aud equals your client_id, nonce matches, and it isn't expired. Use the access_token as a Bearer token against the userinfo endpoint.
04Data

Scopes & claims

Scopes govern what the id_token and userinfo release. Request only what you need — the userinfo endpoint returns exactly the consented claims.

ScopeReleases
openidRequired. The subject identifier (sub) — a stable user id.
emailemail and email_verified.
profilename (the display name).
offline_accessA refresh token, so you can keep the session alive without re-prompting.
GET https://auth.tilldev.dev/v1/oidc/userinfo Authorization: Bearer <access_token> → { "sub": "…", "email": "ada@acme.com", "email_verified": true, "name": "Ada Lovelace" }