Configure Dashboard Authentication
This guide covers configuring authentication for the Omnia dashboard. Choose the mode that fits your deployment:
| Mode | Best For | Complexity |
|---|---|---|
| Anonymous | Development, demos | Minimal |
| Proxy | Existing OAuth2 Proxy setup | Low |
| OAuth | Standalone deployments with IdP | Medium |
| Builtin | Small teams without IdP | Medium |
For agent endpoint authentication (JWT/Istio), see Configure Agent Authentication.
Prerequisites
Section titled “Prerequisites”- Omnia dashboard deployed
- Access to environment configuration
- (For OAuth) Identity provider credentials
Anonymous Mode
Section titled “Anonymous Mode”The default mode with no authentication. All users can access the dashboard as viewers.
Enable Anonymous Mode
Section titled “Enable Anonymous Mode”Set the auth mode environment variable:
OMNIA_AUTH_MODE=anonymousConfigure Anonymous Role
Section titled “Configure Anonymous Role”By default, anonymous users get the viewer role. To change this:
OMNIA_AUTH_ANONYMOUS_ROLE=editor # or adminProxy Mode
Section titled “Proxy Mode”Delegates authentication to a reverse proxy that handles OAuth/OIDC.
How It Works
Section titled “How It Works”- Reverse proxy (OAuth2 Proxy, Authelia, etc.) handles authentication
- Proxy forwards user info in HTTP headers
- Dashboard reads headers and creates session
Enable Proxy Mode
Section titled “Enable Proxy Mode”OMNIA_AUTH_MODE=proxyConfigure Header Names
Section titled “Configure Header Names”Match your proxy’s header configuration:
# Default header names (OAuth2 Proxy compatible)OMNIA_AUTH_PROXY_HEADER_USER=X-Forwarded-UserOMNIA_AUTH_PROXY_HEADER_EMAIL=X-Forwarded-EmailOMNIA_AUTH_PROXY_HEADER_GROUPS=X-Forwarded-GroupsOMNIA_AUTH_PROXY_HEADER_DISPLAY_NAME=X-Forwarded-Preferred-UsernameConfigure Role Mapping
Section titled “Configure Role Mapping”Map identity provider groups to dashboard roles:
# Comma-separated list of groups that get admin roleOMNIA_AUTH_ROLE_ADMIN_GROUPS=omnia-admins,platform-admins
# Comma-separated list of groups that get editor roleOMNIA_AUTH_ROLE_EDITOR_GROUPS=omnia-editors,developers
# Users not in any group get viewer roleOAuth2 Proxy Example
Section titled “OAuth2 Proxy Example”Example OAuth2 Proxy configuration for Google:
# oauth2-proxy values.yamlconfig: clientID: "YOUR_CLIENT_ID" clientSecret: "YOUR_CLIENT_SECRET" cookieSecret: "YOUR_COOKIE_SECRET"
extraArgs: provider: google email-domain: "*" pass-user-headers: true set-xauthrequest: true
ingress: enabled: true hosts: - dashboard.example.comNginx ingress annotation:
nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy.auth.svc.cluster.local/oauth2/auth"nginx.ingress.kubernetes.io/auth-signin: "https://dashboard.example.com/oauth2/start?rd=$escaped_request_uri"nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email,X-Auth-Request-Groups"Authelia Example
Section titled “Authelia Example”Authelia configuration:
# authelia configuration.ymlaccess_control: default_policy: deny rules: - domain: dashboard.example.com policy: two_factor subject: - "group:omnia-users"Traefik middleware:
apiVersion: traefik.containo.us/v1alpha1kind: Middlewaremetadata: name: autheliaspec: forwardAuth: address: http://authelia.auth.svc.cluster.local/api/verify?rd=https://auth.example.com authResponseHeaders: - Remote-User - Remote-Email - Remote-GroupsUpdate dashboard headers to match:
OMNIA_AUTH_PROXY_HEADER_USER=Remote-UserOMNIA_AUTH_PROXY_HEADER_EMAIL=Remote-EmailOMNIA_AUTH_PROXY_HEADER_GROUPS=Remote-GroupsOAuth Mode
Section titled “OAuth Mode”Direct OAuth 2.0 / OpenID Connect integration with identity providers.
How It Works
Section titled “How It Works”- User clicks “Sign in” on login page
- Dashboard redirects to identity provider with PKCE
- User authenticates with IdP
- IdP redirects back with authorization code
- Dashboard exchanges code for tokens
- Dashboard creates session from ID token claims
Enable OAuth Mode
Section titled “Enable OAuth Mode”OMNIA_AUTH_MODE=oauthRequired Configuration
Section titled “Required Configuration”All OAuth deployments need:
# Base URL for callbacks (no trailing slash)OMNIA_BASE_URL=https://dashboard.example.com
# OAuth client credentialsOMNIA_OAUTH_CLIENT_ID=your-client-idOMNIA_OAUTH_CLIENT_SECRET=your-client-secret
# Or mount secret from file (K8s Secret)# OMNIA_OAUTH_CLIENT_SECRET_FILE=/etc/omnia/oauth/client-secretProvider Configuration
Section titled “Provider Configuration”Generic OIDC
Section titled “Generic OIDC”For any OIDC-compliant provider:
OMNIA_OAUTH_PROVIDER=genericOMNIA_OAUTH_ISSUER_URL=https://auth.example.comOMNIA_OAUTH_SCOPES=openid,profile,email,groupsOMNIA_OAUTH_PROVIDER=googleOMNIA_OAUTH_CLIENT_ID=xxx.apps.googleusercontent.comOMNIA_OAUTH_CLIENT_SECRET=GOCSPX-xxxCreate credentials at Google Cloud Console:
- Create OAuth 2.0 Client ID
- Set authorized redirect URI:
https://dashboard.example.com/api/auth/callback - Copy client ID and secret
Azure AD / Entra ID
Section titled “Azure AD / Entra ID”OMNIA_OAUTH_PROVIDER=azureOMNIA_OAUTH_AZURE_TENANT_ID=your-tenant-idOMNIA_OAUTH_CLIENT_ID=your-application-idOMNIA_OAUTH_CLIENT_SECRET=your-client-secretConfigure in Azure Portal:
- Register application in App registrations
- Add redirect URI:
https://dashboard.example.com/api/auth/callback - Create client secret
- Configure API permissions:
openid,profile,email - (Optional) Add
GroupMember.Read.Allfor group claims
OMNIA_OAUTH_PROVIDER=oktaOMNIA_OAUTH_OKTA_DOMAIN=your-domain.okta.comOMNIA_OAUTH_CLIENT_ID=your-client-idOMNIA_OAUTH_CLIENT_SECRET=your-client-secretConfigure in Okta Admin:
- Create OIDC Web Application
- Set sign-in redirect URI:
https://dashboard.example.com/api/auth/callback - Set sign-out redirect URI:
https://dashboard.example.com/login - Assign users/groups to application
GitHub
Section titled “GitHub”OMNIA_OAUTH_PROVIDER=githubOMNIA_OAUTH_CLIENT_ID=your-client-idOMNIA_OAUTH_CLIENT_SECRET=your-client-secretClaim Mapping
Section titled “Claim Mapping”Map OIDC claims to user fields:
# Which claim contains the usernameOMNIA_OAUTH_CLAIM_USERNAME=preferred_username
# Which claim contains the emailOMNIA_OAUTH_CLAIM_EMAIL=email
# Which claim contains the display nameOMNIA_OAUTH_CLAIM_DISPLAY_NAME=name
# Which claim contains groups (supports nested paths)OMNIA_OAUTH_CLAIM_GROUPS=groupsFor Azure AD with nested claims:
OMNIA_OAUTH_CLAIM_GROUPS=wids # Uses role IDs# Or configure group claims in Azure AD token configurationRole Mapping
Section titled “Role Mapping”Same as proxy mode:
OMNIA_AUTH_ROLE_ADMIN_GROUPS=omnia-adminsOMNIA_AUTH_ROLE_EDITOR_GROUPS=omnia-editorsBuiltin Mode
Section titled “Builtin Mode”Self-contained authentication with a local user database. No external identity provider required.
How It Works
Section titled “How It Works”- Users register or are seeded by admin
- Credentials stored in SQLite (default) or PostgreSQL
- Passwords hashed with bcrypt (12 rounds)
- Sessions managed via encrypted cookies
Enable Builtin Mode
Section titled “Enable Builtin Mode”OMNIA_AUTH_MODE=builtinStorage Backend
Section titled “Storage Backend”SQLite (Default)
Section titled “SQLite (Default)”Zero-configuration, perfect for single-instance deployments:
OMNIA_BUILTIN_STORE_TYPE=sqliteOMNIA_BUILTIN_SQLITE_PATH=./data/omnia-users.dbPostgreSQL
Section titled “PostgreSQL”For multi-instance production deployments:
OMNIA_BUILTIN_STORE_TYPE=postgresqlOMNIA_BUILTIN_POSTGRES_URL=postgresql://user:password@localhost:5432/omniaInitial Admin User
Section titled “Initial Admin User”On first run, an admin user is automatically created:
OMNIA_BUILTIN_ADMIN_USERNAME=adminOMNIA_BUILTIN_ADMIN_EMAIL=admin@example.comOMNIA_BUILTIN_ADMIN_PASSWORD=changeme123User Registration
Section titled “User Registration”Control whether new users can sign up:
# Allow public signup (default: false)OMNIA_BUILTIN_ALLOW_SIGNUP=true
# Require email verification (default: false)OMNIA_BUILTIN_VERIFY_EMAIL=truePassword Policy
Section titled “Password Policy”Configure password requirements:
# Minimum password length (default: 8)OMNIA_BUILTIN_MIN_PASSWORD_LENGTH=12Account Security
Section titled “Account Security”Protect against brute force attacks:
# Failed attempts before lockout (default: 5)OMNIA_BUILTIN_MAX_FAILED_ATTEMPTS=5
# Lockout duration in seconds (default: 900 = 15 minutes)OMNIA_BUILTIN_LOCKOUT_DURATION=900Password Reset
Section titled “Password Reset”Configure password reset tokens:
# Token expiration in seconds (default: 3600 = 1 hour)OMNIA_BUILTIN_RESET_TOKEN_EXPIRATION=3600Email Verification
Section titled “Email Verification”For deployments requiring verified emails:
OMNIA_BUILTIN_VERIFY_EMAIL=true
# Token expiration in seconds (default: 86400 = 24 hours)OMNIA_BUILTIN_VERIFICATION_TOKEN_EXPIRATION=86400Kubernetes Example
Section titled “Kubernetes Example”# values.yamldashboard: env: OMNIA_AUTH_MODE: builtin OMNIA_BUILTIN_STORE_TYPE: postgresql OMNIA_BUILTIN_ALLOW_SIGNUP: "false"
envFrom: - secretRef: name: dashboard-builtin-secretapiVersion: v1kind: Secretmetadata: name: dashboard-builtin-secrettype: OpaquestringData: OMNIA_SESSION_SECRET: "your-32-char-secret-here" OMNIA_BUILTIN_POSTGRES_URL: "postgresql://user:pass@postgres:5432/omnia" OMNIA_BUILTIN_ADMIN_PASSWORD: "initial-admin-password"Session Configuration
Section titled “Session Configuration”Configure session behavior for all modes:
# Session encryption secret (required in production!)# Generate with: openssl rand -base64 32OMNIA_SESSION_SECRET=your-32-character-secret-here
# Cookie nameOMNIA_SESSION_COOKIE_NAME=omnia_session
# Session lifetime in seconds (default: 24 hours)OMNIA_SESSION_TTL=86400API Keys
Section titled “API Keys”Enable programmatic access for scripts and CI/CD:
# Enable API key authenticationOMNIA_AUTH_API_KEYS_ENABLED=true
# Maximum keys per user (default: 10)OMNIA_AUTH_API_KEYS_MAX_PER_USER=10
# Default expiration in days (default: 90, 0 = never)OMNIA_AUTH_API_KEYS_DEFAULT_EXPIRATION=90Generate API Key
Section titled “Generate API Key”Users can generate keys from Settings > API Keys, or use the CLI:
cd dashboardnode scripts/generate-api-key.mjs \ --name "CI Pipeline" \ --user-id "user-123" \ --role "editor" \ --expires-in-days 30Use API Key
Section titled “Use API Key”Include the key in requests:
# Using Authorization headercurl -H "Authorization: Bearer omnia_sk_abc123..." \ https://dashboard.example.com/api/agents
# Or using X-API-Key headercurl -H "X-API-Key: omnia_sk_abc123..." \ https://dashboard.example.com/api/agentsKubernetes Deployment
Section titled “Kubernetes Deployment”Using Helm Values
Section titled “Using Helm Values”# values.yamldashboard: env: OMNIA_AUTH_MODE: oauth OMNIA_OAUTH_PROVIDER: google OMNIA_BASE_URL: https://dashboard.example.com
envFrom: - secretRef: name: dashboard-oauth-secretOAuth Secret
Section titled “OAuth Secret”apiVersion: v1kind: Secretmetadata: name: dashboard-oauth-secrettype: OpaquestringData: OMNIA_SESSION_SECRET: "your-32-char-secret-here" OMNIA_OAUTH_CLIENT_ID: "your-client-id" OMNIA_OAUTH_CLIENT_SECRET: "your-client-secret"File-Mounted Secret
Section titled “File-Mounted Secret”For client secret rotation without pod restart:
apiVersion: v1kind: Secretmetadata: name: oauth-client-secrettype: OpaquestringData: client-secret: "your-client-secret"---# In deploymentvolumes: - name: oauth-secret secret: secretName: oauth-client-secretvolumeMounts: - name: oauth-secret mountPath: /etc/omnia/oauth readOnly: trueenv: - name: OMNIA_OAUTH_CLIENT_SECRET_FILE value: /etc/omnia/oauth/client-secretTroubleshooting
Section titled “Troubleshooting”OAuth Login Fails
Section titled “OAuth Login Fails”Symptom: Redirect to IdP works, but callback fails
Check:
- Callback URL matches exactly:
https://dashboard.example.com/api/auth/callback OMNIA_BASE_URLhas no trailing slash- Client secret is correct
- Required scopes are configured in IdP
Session Not Persisting
Section titled “Session Not Persisting”Symptom: User logged out after page refresh
Check:
OMNIA_SESSION_SECRETis set- Cookie is being set (check browser dev tools)
- No proxy stripping cookies
Groups Not Working
Section titled “Groups Not Working”Symptom: User authenticated but has wrong role
Check:
- Groups claim is present in ID token (use jwt.io to decode)
OMNIA_OAUTH_CLAIM_GROUPSmatches your IdP’s claim name- Group names match
OMNIA_AUTH_ROLE_*_GROUPSexactly
Proxy Headers Not Received
Section titled “Proxy Headers Not Received”Symptom: Proxy mode shows anonymous user
Check:
- Proxy is configured to forward headers
- Header names match configuration
- No intermediate proxy stripping headers
- Test with:
curl -vto see headers
Builtin Login Fails
Section titled “Builtin Login Fails”Symptom: Correct credentials rejected
Check:
- User exists in database
- Account not locked (check failed login count)
- Email verified (if
OMNIA_BUILTIN_VERIFY_EMAIL=true) - Database file/connection accessible
Account Locked Out
Section titled “Account Locked Out”Symptom: Login fails with “Account locked”
Fix:
- Wait for lockout duration (default: 15 minutes)
- Or manually reset in database:
UPDATE users SET failed_login_attempts = 0, locked_until = NULL WHERE email = 'user@example.com';
Password Reset Not Working
Section titled “Password Reset Not Working”Symptom: No reset email received
Check:
- Email service configured (or check console logs for token)
- Token not expired (
OMNIA_BUILTIN_RESET_TOKEN_EXPIRATION) - User exists with that email
Next Steps
Section titled “Next Steps”- Authentication Architecture - Understand the full auth model
- Configure Agent Authentication - Secure agent endpoints
- Dashboard Auth Reference - Complete configuration reference
- Manage Workspaces - Set up team isolation and access control