Skip to main content

SSO Setup Guide

Arcan supports three single sign-on (SSO) protocols for authenticating users against external identity providers:

ProtocolUse CaseExamples
OIDCModern web identity providersGoogle, Okta, Azure AD, Auth0, Keycloak
SAMLEnterprise identity federationOkta SAML, Azure AD SAML, ADFS, OneLogin
LDAPOn-premise directory servicesActive 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

  1. Go to Google Cloud Console > Credentials
  2. Create an OAuth 2.0 Client ID (Web application type)
  3. Add the redirect URI: https://<your-arcan-host>/api/v1/auth/oidc/google/callback
  4. 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

  1. In Okta Admin Console, go to Applications > Create App Integration
  2. Select OIDC - OpenID Connect and Web Application
  3. Set the sign-in redirect URI to https://<your-arcan-host>/api/v1/auth/oidc/okta/callback
  4. 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

  1. In Azure Portal, go to App registrations > New registration
  2. Add the redirect URI (Web): https://<your-arcan-host>/api/v1/auth/oidc/azure/callback
  3. Under Certificates & secrets, create a new client secret
  4. 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

  1. In Auth0 Dashboard, go to Applications > Create Application
  2. Select Regular Web Applications
  3. Set the callback URL to https://<your-arcan-host>/api/v1/auth/oidc/auth0/callback
  4. 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

  1. In Keycloak Admin Console, create a new client
  2. Set the Valid Redirect URIs to https://<your-arcan-host>/api/v1/auth/oidc/keycloak/callback
  3. Set Client authentication to On (confidential client)
  4. 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

  1. In Okta Admin Console, go to Applications > Create App Integration
  2. Select SAML 2.0
  3. Set the Single sign-on URL (ACS) to https://<your-arcan-host>/api/v1/auth/saml/okta/acs
  4. Find the Metadata URL under Sign On > Metadata URL
  5. Run the wizard:
arcan auth setup
# Select [2] SAML > [1] Okta
# Enter the Metadata URL from Okta

Azure AD (Entra ID) via SAML

  1. In Azure Portal, go to Enterprise Applications > New Application
  2. Configure single sign-on with SAML
  3. Set the Reply URL (ACS) to https://<your-arcan-host>/api/v1/auth/saml/azure/acs
  4. Note your Tenant ID
  5. 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

  1. In ADFS Management, add a new Relying Party Trust
  2. Set the SAML Assertion Consumer endpoint to https://<your-arcan-host>/api/v1/auth/saml/adfs/acs
  3. 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

  1. Create a service account (e.g., cn=arcan,ou=Service Accounts,dc=example,dc=com)
  2. Grant it read access to the user search base
  3. 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):

  1. Local cache -- ~/.arcan/presets/sso.json (auto-updated from registry)
  2. Registry -- Latest presets from registry.getarcan.dev (cached 24h)
  3. 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
FieldRequiredDescription
nameYesUnique provider identifier
issuerYesOIDC issuer URL (must have /.well-known/openid-configuration)
client_idYesOAuth2 client ID
client_secretYesOAuth2 client secret (encrypted or ${ENV_VAR})
redirect_urlYesOAuth2 callback URL
allowed_domainsNoRestrict login to specific email domains
scopesNoCustom 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
FieldRequiredDescription
nameYesUnique provider identifier
acs_urlYesAssertion Consumer Service URL
entity_idNoSP Entity ID (auto-generated if omitted)
metadata_urlOne ofIdP metadata URL (fetched at startup)
metadata_fileOne ofPath to local IdP metadata XML file
cert_fileNoSP certificate file for signed assertions
key_fileNoSP 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"
FieldRequiredDescription
nameYesUnique provider identifier
urlYesLDAP server URL (ldaps:// or ldap://)
bind_dnYesService account distinguished name
bind_passwordYesService account password (encrypted or ${ENV_VAR})
base_dnYesBase DN for user searches
user_filterNoLDAP search filter (%s = username)
user_attrNoUsername attribute (default: uid)
email_attrNoEmail attribute (default: mail)
name_attrNoDisplay name attribute (default: cn)
group_attrNoGroup membership attribute
start_tlsNoUse StartTLS on plain LDAP connections
skip_verifyNoSkip TLS certificate verification
required_groupNoRequire 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.