Repository navigation
OIDC SSO
🌐 English · Français
Arenet supports OpenID Connect single sign-on for admin login : delegate the authentication flow to your existing IdP (authentik, Keycloak, Authelia, Dex, Auth0, ...) instead of managing local username/password accounts in Arenet's BoltDB.
After OIDC is wired :
- Local admin accounts still work (break-glass, see below)
- The login page exposes a "Sign in with SSO" button
- Successful SSO matches the IdP identity against an allowlist → grants Arenet role (admin or viewer)
- All admin/viewer access flows through the IdP (centralize MFA, audit, account lifecycle)
- An OIDC IdP reachable from Arenet's outbound network
- An OAuth client registered on the IdP with :
- Client type : confidential (Arenet has a client secret)
-
Redirect URI :
https://<your-arenet-host>/api/v1/auth/oidc/callback -
Scopes :
openid,email,profile -
Response type :
code(authorization code flow)
The IdP must publish a valid OIDC discovery doc at {issuer}/.well-known/openid-configuration that returns the right issuer, authorization_endpoint, token_endpoint, jwks_uri.
From your IdP admin UI, note :
-
Issuer URL — e.g.
https://auth.example.com/application/o/arenet/(authentik) orhttps://keycloak.example.com/realms/master(Keycloak) - Client ID — typically a UUID or a slug
- Client Secret — paste-once, store securely
- Sidebar → Settings → OIDC section
- Enabled ✅
-
Issuer URL : paste from step 1 (Arenet auto-strips
/.well-known/openid-configurationif you paste the full discovery URL by accident) - Client ID + Client Secret : paste
-
Scopes : default
openid email profileis fine -
Redirect URL :
https://<your-arenet-host>/api/v1/auth/oidc/callback(must match the IdP-side config) -
Kind : pick
authentik/keycloak/authelia/generic(just for UI label customization) - Save
On Save, Arenet immediately fetches the discovery doc to validate the config. If the fetch fails (unreachable IdP, wrong URL), the Save returns 400 with the error message — your config is NOT persisted.
Once OIDC is wired, you need to tell Arenet which IdP identities can log in. Sidebar → Users → + Add OIDC identity :
-
Email : the identity's email as the IdP will send it in the
emailclaim - Display name : human-readable (optional)
-
Role :
vieweroradmin
Save. The first time this user signs in via SSO, Arenet matches the email → creates a User row → grants the role.
- Open
/loginin a private browser window - Click Sign in with SSO
- You're redirected to the IdP login page
- Authenticate
- IdP redirects back to
/api/v1/auth/oidc/callback?state=...&code=... - Arenet exchanges the code for tokens, validates the ID token signature + issuer + nonce + audience + email_verified
- Allowlist match → session cookie set → you land on
/dashboard
Two roles :
| Role | Can do |
|---|---|
viewer |
Read everything : dashboard, routes list, security events, audit log, cert events, alerts. Cannot mutate. |
admin |
Everything viewer can + create / edit / delete routes, users, OIDC config, alerting rules, backups, restore. |
The role is set per-allowlist-entry (Users page). Changing an entry's role requires a re-login (the role is baked into the session at login time).
Last-admin safeguard : Arenet prevents you from demoting the last local admin account (the break-glass). The API returns 400 ; the UI greys out the demote action. Always keep at least one local admin even when OIDC is wired.
By default Arenet rejects logins where the IdP's email_verified claim is false — typical when a user signed up but never confirmed their email.
For some IdP setups (Keycloak with auto-confirm disabled, internal LDAP-sourced identities that don't have email validation), you may want to accept unverified emails.
- Settings → OIDC → Accept unverified email ✅
- Save
The IdP isn't reachable from the Arenet host. Common causes :
-
DNS : Arenet host can't resolve the IdP FQDN. Fix : add to
/etc/hostsor fix the resolver. -
Hairpin NAT : if the IdP FQDN points at your public IP and your router doesn't support NAT loopback, Arenet (sitting behind the same NAT) can't reach it. Fix :
/etc/hostsoverride pointing at the IdP's LAN IP. -
TLS handshake stall : IdP cert expired, IdP server overloaded, MITM. Fix :
curl -v https://<idp>/.well-known/openid-configurationfrom the Arenet host to confirm. -
Outbound firewall : Arenet daemon user can't egress :443. Fix : check
systemdhardening, nftables.
Arenet enriches the log line with the issuer URL since v2.8.3 — journalctl -u arenet | grep "discovery fetch failed" shows exactly which URL timed out.
The state cookie didn't survive the IdP round-trip. Common causes :
- Different domains for Arenet UI and the callback : the state cookie is set on Arenet's domain ; if the redirect_uri is on a different subdomain, the cookie isn't sent. Fix : ensure the redirect_uri matches the domain you're logging in from.
- Cookie SameSite issue : the IdP doesn't 302 back ; instead it form-POSTs (unusual). Fix : use a IdP-side setting to force GET-based redirect.
- Long IdP login time exceeded cookie max-age : Arenet's state cookie has a short lifetime. Fix : the operator just needs to retry the SSO flow.
If authentik is behind another proxy that doesn't preserve the Host header, authentik builds the discovery doc's issuer field from the upstream's host. Arenet then tries to validate the JWT's iss claim against the discovery doc's issuer → mismatch → token validation fails.
Fix : in authentik, Applications → Providers → your provider → Issuer mode :
- Each provider has a different issuer (recommended) — uses the application slug
- AND make sure the front proxy preserves the Host header (Arenet does this by default since v2.8.4 ; if your stack is
client → other RP → Arenet → authentik, check the other RP)
- A session lasts 24 h (30 days with Remember me), extended by activity.
- After 15 minutes without activity the session is locked: the lock screen asks for your password again — or, for an OIDC account, to sign in again through your identity provider.
- Activity = something you did (a click or keystroke that reaches the server). Since v2.32, the requests the UI sends on its own — notification bell every minute, heartbeat, auto-refresh of Logs / Certificates / CrowdSec live — no longer count: an Arenet tab left open on an unattended computer locks after 15 minutes. Before v2.32 those requests kept the session awake indefinitely.
The first admin you created during the setup wizard is a local account (username + password stored in BoltDB, Argon2id-hashed). This account survives any OIDC-side breakage :
- IdP down for maintenance → log in with the local admin → diagnose
- IdP cert expired → log in with the local admin → reconfigure / disable OIDC temporarily
- IdP irrecoverably lost (you decommissioned authentik without exporting allowlist) → log in with the local admin → re-wire to a new IdP
Keep the local admin password somewhere safe (password manager, sealed envelope, vault). Don't delete it.
# Configure OIDC
curl -b /tmp/jar -X PUT -H "Content-Type: application/json" -d '{
"enabled": true,
"issuerUrl": "https://auth.example.com/application/o/arenet/",
"clientId": "abc123",
"clientSecret": "secret",
"scopes": ["openid","email","profile"],
"redirectUrl": "https://arenet.example.com/api/v1/auth/oidc/callback",
"kind": "authentik"
}' http://localhost:8001/api/v1/settings/oidc
# Add an OIDC identity to the allowlist
curl -b /tmp/jar -X POST -H "Content-Type: application/json" -d '{
"email": "alice@example.com",
"displayName": "Alice",
"role": "admin"
}' http://localhost:8001/api/v1/oidc/allowlistThe OIDC config GET endpoint redacts the client secret (returns "[REDACTED]") so it can be displayed in the UI safely.
-
Routes — wire
forward_authper-route if you want IdP-protected backend apps (different from admin UI SSO) - Backup & Restore — OIDC config + allowlist are included in backup snapshots
- Troubleshooting — OIDC failure diagnosis
-
internal/api/oidc.go— full OIDC implementation - OIDC Discovery spec
- Home · Accueil
- Installation · Installation 🇫🇷
- Routes · Routes 🇫🇷
- TCP / UDP services · Services TCP / UDP 🇫🇷
- DNS Providers · DNS Providers 🇫🇷
- Topology · Topology 🇫🇷
- WAF · WAF 🇫🇷
- CrowdSec · CrowdSec 🇫🇷
- Country Block · Country Block 🇫🇷
- Rate Limit · Rate Limit 🇫🇷
- OIDC SSO · OIDC SSO 🇫🇷
- Forward auth · Forward auth 🇫🇷
- Certificates · Certificats 🇫🇷
- Updating Arenet · Mettre à jour 🇫🇷
- Backup & Restore · Backup & Restore 🇫🇷
- Alerting · Alerting 🇫🇷
- Custom Error Pages · Custom Error Pages 🇫🇷
- API (OpenAPI) · API (OpenAPI) 🇫🇷
- Troubleshooting · Troubleshooting 🇫🇷