SSO Setup Guide
Arcan supports three single sign-on (SSO) protocols for authenticating users against external identity providers:
| Protocol | Use Case | Examples |
|---|---|---|
| OIDC | Modern web identity providers | Google, Okta, Azure AD, Auth0, Keycloak |
| SAML | Enterprise identity federation | Okta SAML, Azure AD SAML, ADFS, OneLogin |
| LDAP | On-premise directory services | Active Directory, OpenLDAP, FreeIPA |
All three can be configured through the interactive wizard or via YAML configuration.
Quick Setup (Interactive Wizard)
The fastest way to configure SSO is the interactive wizard:
arcan auth setup
The wizard walks you through provider selection, credential entry, connection testing, and configuration saving. Secrets are encrypted server-side using the master key before being written to config.yaml.
After setup, test connectivity:
arcan auth test <provider-name>
Provider-Specific Guides
OIDC Providers
Google Workspace
- Go to Google Cloud Console > Credentials
- Create an OAuth 2.0 Client ID (Web application type)
- Add the redirect URI:
https://<your-arcan-host>/api/v1/auth/oidc/google/callback - Run the wizard:
arcan auth setup
# Select [1] OIDC > [1] Google Workspace
# Enter Client ID and Client Secret from the console
Issuer URL: https://accounts.google.com (auto-configured)
Okta
- In Okta Admin Console, go to Applications > Create App Integration
- Select OIDC - OpenID Connect and Web Application
- Set the sign-in redirect URI to
https://<your-arcan-host>/api/v1/auth/oidc/okta/callback - Run the wizard:
arcan auth setup
# Select [1] OIDC > [2] Okta
# Enter your Okta domain (e.g., mycompany)
Issuer URL: https://<domain>.okta.com
Azure AD (Entra ID) via OIDC
- In Azure Portal, go to App registrations > New registration
- Add the redirect URI (Web):
https://<your-arcan-host>/api/v1/auth/oidc/azure/callback - Under Certificates & secrets, create a new client secret
- Run the wizard:
arcan auth setup
# Select [1] OIDC > [3] Azure AD (Entra ID)
# Enter your Azure tenant ID
Issuer URL: https://login.microsoftonline.com/<tenant-id>/v2.0
Auth0
- In Auth0 Dashboard, go to Applications > Create Application
- Select Regular Web Applications
- Set the callback URL to
https://<your-arcan-host>/api/v1/auth/oidc/auth0/callback - Run the wizard:
arcan auth setup
# Select [1] OIDC > [4] Auth0
# Enter your Auth0 domain (e.g., mycompany)
Issuer URL: https://<domain>.auth0.com/
Keycloak
- In Keycloak Admin Console, create a new client
- Set the Valid Redirect URIs to
https://<your-arcan-host>/api/v1/auth/oidc/keycloak/callback - Set Client authentication to On (confidential client)
- Run the wizard:
arcan auth setup
# Select [1] OIDC > [5] Keycloak
# Enter your Keycloak host and realm
Issuer URL: https://<host>/realms/<realm>
SAML Providers
Okta SAML
- In Okta Admin Console, go to Applications > Create App Integration
- Select SAML 2.0
- Set the Single sign-on URL (ACS) to
https://<your-arcan-host>/api/v1/auth/saml/okta/acs - Find the Metadata URL under Sign On > Metadata URL
- Run the wizard:
arcan auth setup
# Select [2] SAML > [1] Okta
# Enter the Metadata URL from Okta
Azure AD (Entra ID) via SAML
- In Azure Portal, go to Enterprise Applications > New Application
- Configure single sign-on with SAML
- Set the Reply URL (ACS) to
https://<your-arcan-host>/api/v1/auth/saml/azure/acs - Note your Tenant ID
- Run the wizard:
arcan auth setup
# Select [2] SAML > [2] Azure AD (Entra ID)
# Enter your Azure tenant ID
Metadata URL: https://login.microsoftonline.com/<tenant>/federationmetadata/2007-06/federationmetadata.xml
ADFS
- In ADFS Management, add a new Relying Party Trust
- Set the SAML Assertion Consumer endpoint to
https://<your-arcan-host>/api/v1/auth/saml/adfs/acs - Run the wizard:
arcan auth setup
# Select [2] SAML > [3] ADFS
# Enter your ADFS hostname (e.g., adfs.example.com)
Metadata URL: https://<hostname>/FederationMetadata/2007-06/FederationMetadata.xml
LDAP Providers
Active Directory
- Create a service account (e.g.,
cn=arcan,ou=Service Accounts,dc=example,dc=com) - Grant it read access to the user search base
- Run the wizard:
arcan auth setup
# Select [3] LDAP > [1] Active Directory
# Enter hostname, bind DN, password, and base DN
Pre-filled defaults for Active Directory:
- Port:
636(LDAPS) - User filter:
(&(objectClass=person)(sAMAccountName=%s)) - Username attribute:
sAMAccountName - Email attribute:
mail - Display name attribute:
displayName
OpenLDAP
arcan auth setup
# Select [3] LDAP > [2] OpenLDAP
Pre-filled defaults for OpenLDAP:
- Port:
636(LDAPS) - User filter:
(&(objectClass=inetOrgPerson)(uid=%s)) - Username attribute:
uid - Email attribute:
mail - Display name attribute:
cn
FreeIPA
arcan auth setup
# Select [3] LDAP > [3] FreeIPA
Pre-filled defaults for FreeIPA:
- Port:
636(LDAPS) - User filter:
(&(objectClass=person)(uid=%s)) - Username attribute:
uid - Base DN hint:
cn=users,cn=accounts,dc=example,dc=com
Provider Presets
Arcan ships with built-in presets for common identity providers. These presets auto-fill configuration like issuer URLs, metadata templates, and LDAP attributes.
How Presets Work
Presets are loaded from three sources (in priority order):
- Local cache --
~/.arcan/presets/sso.json(auto-updated from registry) - Registry -- Latest presets from
registry.getarcan.dev(cached 24h) - Embedded -- Compiled into the binary (fallback when offline)
When you run arcan auth setup, the wizard automatically loads the latest presets
to populate the provider selection menu and auto-fill configuration values.
Updating Presets
Presets auto-update when running arcan auth setup. To manually update:
arcan auth update-presets
This fetches the latest presets from the registry and caches them locally.
Contributing Presets
To add a new identity provider to the official presets, submit a PR to
getarcan/arcan updating internal/presets/defaults.json. See the
Preset Framework page for the JSON schema and contribution guide.
Manual YAML Configuration
All SSO providers are configured in ~/.arcan/config.yaml under the auth section.
OIDC Configuration
auth:
oidc:
- name: google
issuer: https://accounts.google.com
client_id: "123456789.apps.googleusercontent.com"
client_secret: "arcan:v1:encrypted-secret-here"
redirect_url: https://arcan.example.com/api/v1/auth/oidc/google/callback
allowed_domains:
- example.com
scopes:
- openid
- email
- profile
| Field | Required | Description |
|---|---|---|
name | Yes | Unique provider identifier |
issuer | Yes | OIDC issuer URL (must have /.well-known/openid-configuration) |
client_id | Yes | OAuth2 client ID |
client_secret | Yes | OAuth2 client secret (encrypted or ${ENV_VAR}) |
redirect_url | Yes | OAuth2 callback URL |
allowed_domains | No | Restrict login to specific email domains |
scopes | No | Custom OAuth2 scopes (defaults: openid, email, profile) |
SAML Configuration
auth:
saml:
- name: okta
acs_url: https://arcan.example.com/api/v1/auth/saml/okta/acs
entity_id: https://arcan.example.com/api/v1/auth/saml/okta
metadata_url: https://mycompany.okta.com/app/abcdef/sso/saml/metadata
| Field | Required | Description |
|---|---|---|
name | Yes | Unique provider identifier |
acs_url | Yes | Assertion Consumer Service URL |
entity_id | No | SP Entity ID (auto-generated if omitted) |
metadata_url | One of | IdP metadata URL (fetched at startup) |
metadata_file | One of | Path to local IdP metadata XML file |
cert_file | No | SP certificate file for signed assertions |
key_file | No | SP private key file for signed assertions |
LDAP Configuration
auth:
ldap:
- name: active-directory
url: ldaps://ldap.example.com:636
bind_dn: "cn=arcan,ou=Service Accounts,dc=example,dc=com"
bind_password: "arcan:v1:encrypted-password-here"
base_dn: "dc=example,dc=com"
user_filter: "(&(objectClass=person)(sAMAccountName=%s))"
user_attr: sAMAccountName
email_attr: mail
name_attr: displayName
group_attr: memberOf
required_group: "cn=arcan-users,ou=Groups,dc=example,dc=com"
| Field | Required | Description |
|---|---|---|
name | Yes | Unique provider identifier |
url | Yes | LDAP server URL (ldaps:// or ldap://) |
bind_dn | Yes | Service account distinguished name |
bind_password | Yes | Service account password (encrypted or ${ENV_VAR}) |
base_dn | Yes | Base DN for user searches |
user_filter | No | LDAP search filter (%s = username) |
user_attr | No | Username attribute (default: uid) |
email_attr | No | Email attribute (default: mail) |
name_attr | No | Display name attribute (default: cn) |
group_attr | No | Group membership attribute |
start_tls | No | Use StartTLS on plain LDAP connections |
skip_verify | No | Skip TLS certificate verification |
required_group | No | Require membership in this group DN |
How Secrets Are Encrypted
When using the interactive wizard with a running Arcan server, secrets (OIDC client secrets, LDAP bind passwords) are encrypted using the server's master key via the /encrypt endpoint. The encrypted value is stored with an arcan:v1: prefix:
client_secret: "arcan:v1:AES256GCM:base64-ciphertext-here"
At startup, the server decrypts these values using its master key. This means:
- Secrets never appear in plaintext in
config.yaml - The config file can be safely committed to version control (if desired)
- Secrets are tied to the specific server's master key
If the server is not running during setup, the wizard falls back to environment variable references (${ARCAN_OIDC_OKTA_SECRET}), which you must set before starting the server.
Troubleshooting
OIDC Discovery Failed
OIDC Discovery failed: connection refused
Causes:
- Incorrect issuer URL (check for typos)
- Network connectivity issues (firewall, DNS)
- The identity provider is down
Fix: Verify the issuer URL opens in a browser: <issuer>/.well-known/openid-configuration
SAML Metadata Fetch Failed
SAML Metadata fetch failed: metadata URL returned HTTP 404
Causes:
- Wrong metadata URL
- Application not configured in the IdP yet
- Authentication required to access metadata
Fix: Check the IdP's admin console for the correct metadata URL. Some providers require the SAML application to be fully configured before the metadata endpoint is available.
LDAP Connection Failed
LDAP connection test failed: connection failed: dial tcp: connection refused
Causes:
- Wrong hostname or port
- LDAP server not running
- Firewall blocking the connection
- Using
ldaps://but the server does not support TLS on that port
Fix: Verify the server is reachable with ldapsearch or telnet <host> <port>.
LDAP Bind Failed
LDAP connection test failed: service account bind failed: invalid credentials
Causes:
- Wrong bind DN or password
- Service account is locked or disabled
- Password has expired
Fix: Test the credentials with ldapwhoami -H ldaps://<host>:636 -D "<bind_dn>" -W.
Encrypted Secret Not Decrypting
WARN failed to decrypt OIDC client_secret -- check master key
Causes:
- Master key has changed since the secret was encrypted
- Config was copied from a different Arcan instance
Fix: Re-run arcan auth setup to re-encrypt the secret with the current master key.
Advanced Configuration
Custom OIDC Scopes
Override the default scopes (openid, email, profile) for providers that use non-standard claims:
auth:
oidc:
- name: custom-idp
issuer: https://idp.example.com
client_id: "..."
client_secret: "..."
redirect_url: "..."
scopes:
- openid
- email
- profile
- groups
- custom:read
Domain Filtering
Restrict OIDC login to specific email domains:
auth:
oidc:
- name: google
issuer: https://accounts.google.com
client_id: "..."
client_secret: "..."
redirect_url: "..."
allowed_domains:
- example.com
- subsidiary.com
Users with email addresses outside the allowed domains will be rejected.
LDAP Group Requirement
Restrict LDAP login to members of a specific group:
auth:
ldap:
- name: active-directory
url: ldaps://ldap.example.com:636
bind_dn: "..."
bind_password: "..."
base_dn: "dc=example,dc=com"
required_group: "cn=arcan-users,ou=Groups,dc=example,dc=com"
Multiple Providers
You can configure multiple providers of the same or different types. Users will choose their provider at login:
auth:
oidc:
- name: google
issuer: https://accounts.google.com
# ...
- name: okta
issuer: https://mycompany.okta.com
# ...
ldap:
- name: corporate-ad
url: ldaps://dc1.example.com:636
# ...
Non-Interactive Setup
For automation and CI/CD, use flag-based setup:
# OIDC
arcan auth setup --type oidc --name okta \
--issuer https://mycompany.okta.com \
--client-id 0oa1b2c3d4e5f6 \
--client-secret "$OIDC_SECRET"
# SAML
arcan auth setup --type saml --name corporate \
--metadata-url https://idp.example.com/saml/metadata
# LDAP
arcan auth setup --type ldap --name active-directory \
--ldap-url ldaps://ldap.example.com:636 \
--bind-dn "cn=arcan,ou=services,dc=example,dc=com" \
--bind-password "$BIND_PW" \
--base-dn "ou=users,dc=example,dc=com"
Debug Mode
For detailed error output during setup, enable debug mode:
arcan auth setup --debug
This shows full error details including HTTP response bodies, TLS handshake errors, and LDAP protocol-level messages.