How to Configure OIDC/SSO Authentication with Google, Apple, or Authentik in TREK
TREK implements a complete OpenID Connect (OIDC) flow that enables Single Sign-On (SSO) with any standards-compliant provider, featuring automatic user provisioning, PKCE security, and a built-in admin interface for configuration.
The TREK open-source repository provides a production-ready OIDC implementation that supports Google, Apple, Authentik, Keycloak, and custom Identity Providers. The architecture separates frontend administration from backend OAuth2 handling, storing configuration in the database and executing the authorization code flow with PKCE protection.
Understanding TREK's OIDC Architecture
TREK's SSO implementation consists of three distinct layers that handle configuration, authentication, and user provisioning:
- Frontend Admin Interface (
client/src/pages/admin/AdminSettingsTab.tsx, lines 30-95) – Provides the UI for enabling SSO and entering provider credentials. - OIDC Controller (
server/src/nest/oidc/oidc.controller.ts) – Implements the OAuth2 endpoints/login,/callback, and/exchangeusing the authorization code flow with PKCE. - OIDC Service (
server/src/nest/oidc/oidc.service.ts) – Wraps the legacy OIDC helper to perform discovery, token validation, and user lookup/creation.
The authentication flow follows this sequence: the user clicks the SSO button on LoginPage.tsx, which redirects to /api/auth/oidc/login. The controller generates a PKCE code challenge, stores a trek_oidc_state cookie, discovers the provider's .well-known/openid-configuration, and redirects to the provider. After authentication, the provider returns to /api/auth/oidc/callback where TREK validates the state, exchanges the code for tokens, verifies the id_token, and provisions the user. Finally, /api/auth/oidc/exchange converts the short-lived authorization code into a JWT stored in the trek_auth cookie.
Configuring OIDC via the Admin UI
To enable SSO authentication through the web interface:
- Log in to TREK as an administrator.
- Navigate to Admin → Settings → Single Sign-On (OIDC).
- Toggle "SSO Login" to display the provider button on the login page.
- (Optional) Toggle "SSO Auto-Provisioning" to automatically create local user accounts for new SSO users.
- Configure the provider fields:
- Display name – The label shown on the login button (e.g., "Google" or "Authentik").
- Issuer URL – The base URL of the OIDC provider (see provider-specific notes below).
- Discovery URL – Leave empty unless the provider uses a non-standard discovery endpoint.
- Client ID – The OAuth2 client identifier from your provider.
- Client Secret – The client secret (or JWT for Apple).
Click Save to persist the configuration to the database. The AdminSettingsTab.tsx component validates the payload before sending a PUT request to /api/admin/oidc.
Provider-Specific Configuration Details
- Issuer:
https://accounts.google.com - Discovery: Automatically resolved to
https://accounts.google.com/.well-known/openid-configuration - Requirements: Standard OAuth2 client ID and client secret from Google Cloud Console.
Apple
- Issuer:
https://appleid.apple.com - Discovery:
https://appleid.apple.com/.well-known/openid-configuration - Requirements: Client ID (Services ID) and a signed JWT as the client secret. Apple requires you to generate a JWT using your private key with specific claims.
Authentik
- Issuer: Your Authentik instance URL (e.g.,
https://auth.example.com) - Discovery: You must provide a custom Discovery URL because Authentik does not always publish discovery documents at the standard
/.well-known/openid-configurationpath relative to the issuer. - Requirements: Application client ID and client secret from the Authentik provider configuration.
Manual Configuration via REST API
For automated deployments or infrastructure-as-code setups, configure OIDC directly via the API:
curl -X PUT https://your-trek.example.com/api/admin/oidc \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin-jwt>" \
-d '{
"issuer": "https://accounts.google.com",
"discovery_url": null,
"client_id": "YOUR_GOOGLE_CLIENT_ID",
"client_secret": "YOUR_GOOGLE_CLIENT_SECRET",
"display_name": "Google",
"oidc_login": true,
"oidc_registration": true
}'
Replace the JSON values with your provider's specific configuration. For Apple, replace client_secret with your signed JWT. For Authentik, include the discovery_url field pointing to your application's OpenID configuration endpoint.
Troubleshooting Common OIDC Issues
When authentication fails, TREK redirects to the login page with specific error codes in the query string:
oidc_error=state_missing: The browser did not send thetrek_oidc_statecookie. Ensure third-party cookies are enabled and not blocked by browser privacy settings.oidc_error=issuer_not_https: Production deployments require HTTPS issuer URLs. The validation logic inoidc.controller.tsenforces this security constraint.oidc_error=no_email: The Identity Provider did not return an email claim. Verify your provider is configured to release theemailscope and that the user has an email address associated with their account.oidc_error=token_failed: Token exchange or validation failed. Check the server logs for messages prefixed with"[OIDC] Token exchange failed:"to view the specific error from the provider.
All error messages are internationalized using keys in shared/src/i18n/*/login.ts (e.g., login.oidcFailed), allowing customization of user-facing error text.
Summary
- TREK supports any OIDC-compliant provider including Google, Apple, and Authentik through a unified configuration interface in
AdminSettingsTab.tsx. - The OAuth2 flow uses PKCE (Proof Key for Code Exchange) for enhanced security, implemented in
oidc.controller.tswith state cookie validation. - Configuration requires the issuer URL, client ID, client secret, and optionally a custom discovery URL for providers like Authentik.
- Auto-provisioning can be enabled to automatically create local user accounts when users first authenticate via SSO.
- Manual configuration is available via the
PUT /api/admin/oidcendpoint for automated deployments.
Frequently Asked Questions
What OIDC providers does TREK support?
TREK supports any provider implementing the OpenID Connect Core 1.0 specification, including Google, Apple, Authentik, Keycloak, Okta, and Azure AD. The implementation discovers provider endpoints automatically via .well-known/openid-configuration, or accepts manual discovery URLs for non-standard deployments as configured in the Admin Settings UI.
How does TREK handle user provisioning for SSO users?
When SSO Auto-Provisioning is enabled, the oidc.service.ts layer automatically creates or updates local user records during the callback phase. It extracts the email claim from the id_token or userinfo endpoint, checks for existing users in the database, and creates new accounts with the authenticated email address. If auto-provisioning is disabled, only existing users with matching emails can log in via SSO.
Can I configure OIDC without using the web UI?
Yes, TREK exposes the PUT /api/admin/oidc endpoint that accepts JSON payloads containing issuer, discovery_url, client_id, client_secret, display_name, oidc_login, and oidc_registration fields. This allows infrastructure-as-code deployment using curl, Terraform, or custom scripts. The endpoint requires an admin JWT token for authorization.
What should I do if users see "oidc_error=token_failed"?
This error indicates a failure in the token exchange or validation step in oidc.controller.ts. Verify that your Client Secret is correct (remember that Apple requires a JWT, not a static string), ensure the Issuer URL matches exactly what the provider expects (including trailing slashes), and check that the TREK server can reach the provider's token endpoint. Review server logs for the specific error message prefixed with "[OIDC] Token exchange failed:" to diagnose the root cause.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →