OpenID Connect (OIDC)
Authentication using penID Connect (OIDC) providers.
π OpenID Connect (OIDC) Login
Kurrier supports authentication using OpenID Connect (OIDC) providers.
Currently, Google login is available out of the box, and a generic OIDC provider lets you plug in any spec-compliant IdP such as Authelia, Keycloak, Authentik, Zitadel, Okta, Auth0, or Microsoft Entra ID β configured entirely through environment variables.
β¨ Currently Supported
- Google OIDC Login
- Generic OIDC Login (any spec-compliant OpenID Connect provider)
Additional dedicated providers can be implemented by adding another OIDC route and provider configuration.
π§ How It Works
Kurrier uses the standard:
- OAuth 2.0 Authorization Code Flow
- PKCE (Proof Key for Code Exchange)
- OpenID Connect identity claims
The authentication flow is:
- User clicks βContinue with Googleβ
- Kurrier redirects the user to Google
- Google authenticates the user
- Google redirects back to Kurrier callback route
- Kurrier verifies the response
- User account + workspace are created automatically if they do not exist
- Session cookie is issued
- User is redirected into the workspace dashboard
π¦ Environment Variables
Add the following to your .env:
env
OIDC_GOOGLE_CLIENT_ID=your_google_client_id
OIDC_GOOGLE_CLIENT_SECRET=your_google_client_secretπ Creating Google OAuth Credentials
- Open Google Cloud Console
- Navigate to:
- APIs & Services β Credentials
- Click:
- Create Credentials β OAuth Client ID
- Choose:
- Web Application
Authorized Redirect URI
Add:
http://localhost:3000/api/auth/oidc/google/callbackFor production:
https://your-domain.com/api/auth/oidc/google/callbackπ Route Structure
Google OIDC flow is implemented using App Router route handlers.
app/
βββ api/
βββ auth/
βββ oidc/
βββ google/
βββ route.ts
βββ callback/
βββ route.tsπ Start Route
The start route:
/api/auth/oidc/googleResponsibilities:
- Discover Google OIDC configuration
- Generate PKCE verifier/challenge
- Generate state token
- Store temporary cookies
- Redirect user to Google authorization endpoint
β© Callback Route
The callback route:
/api/auth/oidc/google/callbackResponsibilities:
- Validate PKCE verifier
- Validate state
- Exchange authorization code for tokens
- Read user claims
- Create or locate user
- Create auth provider/account records
- Create session cookie
- Redirect into workspace
π Database Records
Successful OIDC login creates:
users
Primary application user.
workspaces
Default workspace for the user.
workspace_members
Workspace ownership membership.
auth_providers
OIDC provider metadata for the workspace.
auth_accounts
Provider-linked external identity record.
π Security Notes
Kurrier uses:
- PKCE
- State validation
- HttpOnly session cookies
- Verified Google email requirement
- Signed JWT session tokens
Sensitive provider tokens are never logged in production.
π Generic OIDC Provider
Any OpenID Connect provider that supports discovery (/.well-known/openid-configuration) and the Authorization Code Flow with PKCE can be used for login β no code changes required.
Environment Variables
OIDC_ISSUER_URL=https://auth.example.com
OIDC_CLIENT_ID=kurrier
OIDC_CLIENT_SECRET=your_client_secret
# Optional
OIDC_PROVIDER_NAME=My Company SSO # label on the login button (default: "SSO")
OIDC_SCOPES=openid email profile # default shown
OIDC_TOKEN_AUTH_METHOD=client_secret_basic # or client_secret_post
OIDC_REQUIRE_VERIFIED_EMAIL=true # set to "false" to accept unverified emailsThe generic login button appears on the login and signup pages as soon as OIDC_ISSUER_URL, OIDC_CLIENT_ID and OIDC_CLIENT_SECRET are all set.
Redirect URI
Register the following redirect URI with your provider:
https://your-domain.com/api/auth/oidc/generic/callbackRoute Structure
/api/auth/oidc/generic β start route (discovery, PKCE, state, redirect)
/api/auth/oidc/generic/callback β callback route (code exchange, user provisioning, session)Provider Notes
- Token endpoint authentication defaults to
client_secret_basic(the OAuth 2.0 default). Some providers default to or requireclient_secret_postβ setOIDC_TOKEN_AUTH_METHODaccordingly. - Claims: Kurrier needs the
emailandsubclaims. If the ID token does not carryemail(e.g. Authelia exposes profile claims only through the userinfo endpoint), Kurrier automatically falls back to the userinfo endpoint. - Identity mapping: returning users are identified by the stable
issuer + subpair stored inauth_accountsβ never by email. A change to the email reported by the IdP does not change which Kurrier user is authenticated. - User provisioning: on the very first login, the verified email claim is used once, to link the external identity to an existing Kurrier user or to create a new user + default workspace. Unverified emails are rejected by default.
- Unverified emails: some IdPs never set
email_verified: true(e.g. OpenCloud's native OIDC provider). SetOIDC_REQUIRE_VERIFIED_EMAIL=falseto accept the email claim regardless of theemail_verifiedvalue. Leave this unset (ortrue) unless your IdP requires it β it's a deliberate security default.
Example: Authelia
identity_providers:
oidc:
clients:
- client_id: kurrier
client_name: Kurrier
client_secret: '$pbkdf2-sha512$...' # hashed secret
public: false
authorization_policy: one_factor
redirect_uris:
- https://mail.example.com/api/auth/oidc/generic/callback
scopes:
- openid
- email
- profile
userinfo_signed_response_alg: noneAuthelia authenticates clients with client_secret_basic by default, which matches Kurrier's default β no extra configuration needed.
Example: Keycloak
- Create a new confidential client in your realm
- Enable Standard Flow (Authorization Code)
- Set the redirect URI to
https://your-domain.com/api/auth/oidc/generic/callback - Use the realm issuer URL, e.g.
https://keycloak.example.com/realms/myrealm, asOIDC_ISSUER_URL
β Adding More Providers
Additional providers can be added by implementing another OIDC route pair.
Examples:
/api/auth/oidc/github
/api/auth/oidc/microsoft
/api/auth/oidc/keycloakMost providers only require:
- Discovery URL
- Client ID
- Client Secret
- Redirect URI
- Scope configuration
The rest of the flow remains identical.
π References
- OpenID Connect: https://openid.net/connect/
- OAuth 2.0 PKCE: https://oauth.net/2/pkce/
- openid-client: https://github.com/panva/openid-client