Files
sure/config/auth.yml
Josh Waldrep 14993d871c feat: comprehensive SSO/OIDC upgrade with enterprise features
Multi-provider SSO support:
   - Database-backed SSO provider management with admin UI
   - Support for OpenID Connect, Google OAuth2, GitHub, and SAML 2.0
   - Flipper feature flag (db_sso_providers) for dynamic provider loading
   - ProviderLoader service for YAML or database configuration

   Admin functionality:
   - Admin::SsoProvidersController for CRUD operations
   - Admin::UsersController for super_admin role management
   - Pundit policies for authorization
   - Test connection endpoint for validating provider config

   User provisioning improvements:
   - JIT (just-in-time) account creation with configurable default role
   - Changed default JIT role from admin to member (security)
   - User attribute sync on each SSO login
   - Group/role mapping from IdP claims

   SSO identity management:
   - Settings::SsoIdentitiesController for users to manage connected accounts
   - Issuer validation for OIDC identities
   - Unlink protection when no password set

   Audit logging:
   - SsoAuditLog model tracking login, logout, link, unlink, JIT creation
   - Captures IP address, user agent, and metadata

   Advanced OIDC features:
   - Custom scopes per provider
   - Configurable prompt parameter (login, consent, select_account, none)
   - RP-initiated logout (federated logout to IdP)
   - id_token storage for logout

   SAML 2.0 support:
   - omniauth-saml gem integration
   - IdP metadata URL or manual configuration
   - Certificate and fingerprint validation
   - NameID format configuration
2026-01-03 17:56:42 -05:00

70 lines
3.0 KiB
YAML

default: &default
local_login:
# When false, local email/password login is disabled for all users unless
# AUTH_LOCAL_ADMIN_OVERRIDE_ENABLED is true and the user is a super admin.
enabled: <%= ENV.fetch("AUTH_LOCAL_LOGIN_ENABLED", "true") == "true" %>
# When true and local_login.enabled is false, allow super admins to use
# local login as an emergency override. Regular users remain SSO-only.
admin_override_enabled: <%= ENV.fetch("AUTH_LOCAL_ADMIN_OVERRIDE_ENABLED", "false") == "true" %>
jit:
# Controls behavior when a user signs in via SSO and no OIDC identity exists.
# - "create_and_link" (default): create a new user + family when no match exists
# - "link_only": require an existing user; block JIT creation
mode: <%= ENV.fetch("AUTH_JIT_MODE", "create_and_link") %>
# Optional comma-separated list of domains (e.g. "example.com,corp.com").
# When non-empty, JIT SSO account creation is only allowed for these domains.
# When empty, all domains are allowed (current behavior).
allowed_oidc_domains: <%= ENV.fetch("ALLOWED_OIDC_DOMAINS", "") %>
providers:
# Generic OpenID Connect provider (e.g., Keycloak, Authentik, other OIDC issuers).
# This maps to the existing :openid_connect OmniAuth strategy and keeps
# backwards-compatible behavior for self-hosted setups using OIDC_* env vars.
#
# For the default OIDC provider, use these ENV vars:
# OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_REDIRECT_URI
#
# To add additional OIDC providers, add more entries with unique names and use
# provider-specific ENV vars with the pattern: OIDC_<UPPERCASE_NAME>_*
# Example for a provider named "keycloak":
# OIDC_KEYCLOAK_ISSUER, OIDC_KEYCLOAK_CLIENT_ID,
# OIDC_KEYCLOAK_CLIENT_SECRET, OIDC_KEYCLOAK_REDIRECT_URI
- id: "oidc"
strategy: "openid_connect"
name: "openid_connect"
label: <%= ENV.fetch("OIDC_BUTTON_LABEL", "Sign in with OpenID Connect") %>
icon: <%= ENV.fetch("OIDC_BUTTON_ICON", "key") %>
# Per-provider credentials (optional, falls back to global OIDC_* vars)
issuer: <%= ENV["OIDC_ISSUER"] %>
client_id: <%= ENV["OIDC_CLIENT_ID"] %>
client_secret: <%= ENV["OIDC_CLIENT_SECRET"] %>
redirect_uri: <%= ENV["OIDC_REDIRECT_URI"] %>
# Optional Google OAuth provider. Requires the omniauth-google-oauth2 gem
# and GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET env vars.
- id: "google"
strategy: "google_oauth2"
name: "google_oauth2"
label: <%= ENV.fetch("GOOGLE_BUTTON_LABEL", "Sign in with Google") %>
icon: <%= ENV.fetch("GOOGLE_BUTTON_ICON", "google") %>
# Optional GitHub OAuth provider. Requires the omniauth-github gem and
# GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET env vars.
- id: "github"
strategy: "github"
name: "github"
label: <%= ENV.fetch("GITHUB_BUTTON_LABEL", "Sign in with GitHub") %>
icon: <%= ENV.fetch("GITHUB_BUTTON_ICON", "github") %>
development:
<<: *default
test:
<<: *default
production:
<<: *default