Overview
This guide covers all authentication features including OIDC, OAuth2, SAML 2.0, database-backed provider management, JIT provisioning, role mapping, user management, and audit logging.Configuration methods
Database-backed providers (recommended)
Manage providers through the admin UI without server restarts:- Changes take effect immediately
- No server restarts required
- Web-based configuration at
/admin/sso_providers - Audit trail for all changes
YAML-based providers (legacy)
Configure providers inconfig/auth.yml. Requires server restart for changes.
OIDC configuration
Supported providers
OIDC works with any compliant provider:- Google Workspace
- Microsoft Entra ID (Azure AD)
- Okta
- Auth0
- Keycloak
- Authentik
- GitLab
Basic OIDC setup
Create OAuth client in your IdP
authentik, use:Add provider in admin UI
/admin/sso_providers and click Add Provider:Configure role mapping
Test the integration
Multiple OIDC providers
Configure multiple providers simultaneously (e.g., Keycloak + Authentik):name field, which determines the callback URL path. For example, a provider named authentik uses https://your-domain.com/auth/authentik/callback.
OAuth2 configuration
Use OAuth2 for providers without OIDC support (GitHub, GitLab, Discord, Slack).GitHub example
Create OAuth App
Configure in admin UI
Token endpoint authentication
The application supports multiple authentication methods:client_secret_post(default): Send credentials in request bodyclient_secret_basic: Send credentials in Authorization header
SAML 2.0 configuration
Service Provider metadata
Your application provides SAML metadata at:Okta SAML setup
Create SAML application
- Go to Applications → Create App Integration
- Select SAML 2.0
Configure SAML settings
Configure attribute statements
Get IdP metadata
- Identity Provider Single Sign-On URL
- Identity Provider Issuer
- X.509 Certificate
Configure in admin UI
Azure AD SAML setup
Create enterprise application
- Go to Microsoft Entra ID → Enterprise applications
- Click New application → Create your own application
- Select Integrate any other application (Non-gallery)
Configure SAML
Configure attributes
Download metadata
Database-backed provider management
Admin UI features
Access at/admin/sso_providers:
- Add, edit, delete providers without server restarts
- Enable/disable providers with a toggle
- Test login flows before enabling
- View callback URLs with copy button
- Encrypted storage of client secrets
- Audit trail of all changes
Security features
- Client secrets encrypted at rest using Rails 7.2 ActiveRecord Encryption
- Rate limiting: 10 requests/minute per IP on admin endpoints
- Discovery endpoint validation for OIDC providers
- Issuer validation to prevent impersonation attacks
- Super admin role required for provider management
Seeding providers from YAML
Migrate existing YAML configuration to database:Migration workflow
Backup configuration
Run migrations
Seed providers
Enable database source
Restart application
Verify
[ProviderLoader] Loaded N provider(s) from databaseLocal login control
Disable local login (SSO-only)
- Email/password form hidden
POST /sessionswith local credentials blocked- Password reset routes disabled
/password/edit(self-service password change) is blocked — users are redirected away and cannot set a local password while local login is disabled- Users must authenticate via SSO
Emergency admin override
Allow super admins to log in locally during IdP outages:- Login page shows email/password form with admin-only note
- Super admins can log in with local passwords
- Super admins can still access
/password/editand set a local password - Regular users are blocked from the password change page and redirected away
- Override logins are logged
JIT user provisioning
Provisioning modes
Domain restrictions
Default roles
Configure in admin UI under Role Mapping:- Default Role: Assigned to all JIT-created users (e.g.,
member) - Group Mappings: Map IdP groups to application roles
admin role for that family regardless of the default role setting. Super admin accounts retain their elevated defaults. This ensures the first user of a new family always has the access needed to configure it.
Role mapping
Group-to-role mapping
Map identity provider groups to application roles:super_admin > admin > member).
OIDC group mapping
Ensure your OIDC provider includes groups:SAML attribute mapping
Configure group attribute in SAML provider:Role synchronization
Roles are synchronized on every login:- Fetch current groups from IdP
- Apply group-to-role mappings
- Update user’s roles
- Remove roles no longer mapped
/admin/users → Sync Roles from SSO.
User management
Admin interface
Access at/admin/users:
- View all users with roles, auth methods, last login
- Search and filter by role, provider, status
- View connected SSO accounts
- Manage user roles manually
- Suspend/reactivate/delete users
- View authentication history
Connected accounts
Users can manage their own connected accounts at/settings/security under Connected Accounts:
- View all connected SSO providers with the last-used timestamp
- Connect additional providers by signing in with them
- Disconnect a provider using the Disconnect button
unlink event.
User actions
Deactivate user: Immediately cut off all access without removing data. All web sessions are destroyed, all OAuth tokens and API keys are revoked, and every subsequent login attempt is rejected with HTTP 401.Audit logging
Event types
Access logs at/admin/sso_audit_logs:
Authentication events:
login: Successful SSO loginlogin_failed: Failed login attemptlogout: User logoutlogout_idp: RP-initiated federated logoutlink: SSO account linked to userunlink: SSO account unlinkedjit_account_created: New account created via JIT provisioning
Log retention
- Standard: 90 days in database
- Extended: 1 year (database + archive)
- Compliance: 7 years (archive storage)
Monitoring
Set up alerts for:- Multiple failed login attempts (brute force detection)
- Provider configuration changes
- Unusual login locations
- Role escalations
Troubleshooting
Provider not appearing on login page
YAML mode:- Check required environment variables are set (
OIDC_ISSUER,OIDC_CLIENT_ID,OIDC_CLIENT_SECRET)
- Verify provider is enabled in
/admin/sso_providers - Check
AUTH_PROVIDERS_SOURCE=dbis set - Review application logs for provider loading messages
Discovery endpoint validation fails
When adding an OIDC provider:- Ensure issuer URL is correct and accessible
- Check firewall rules allow outbound HTTPS
- Verify issuer returns valid JSON with
issuerfield - For self-signed certificates, configure SSL verification
Callback URL mismatch
Each provider requires exact callback URL match: Format:https://yourdomain.com/auth/<provider_name>/callback
Examples:
- Keycloak:
https://yourdomain.com/auth/keycloak/callback - Authentik:
https://yourdomain.com/auth/authentik/callback - Google Workspace:
https://yourdomain.com/auth/google/callback
/auth/openid_connect/callback only apply to a legacy provider whose name is literally openid_connect.
Groups not syncing
- Add
groupsscope to OIDC configuration - Verify IdP includes groups in token/assertion
- Check group attribute name matches IdP configuration
- Review audit logs to see what groups are received
- Some IdPs require additional configuration to include groups
POST /api/v1/auth/sso_create_account returns “account already exists”
When a mobile SSO account creation attempt conflicts with an existing record (for example, the same email address or identity is already registered), the API returns HTTP 422 with:
Security considerations
Encryption
- Client secrets encrypted at rest using Rails 7.2 ActiveRecord Encryption
- In self-hosted mode, encryption keys are derived from
SECRET_KEY_BASEunless you set dedicatedACTIVE_RECORD_ENCRYPTION_*keys - Keep the same
SECRET_KEY_BASEfor the lifetime of an existing instance. Changing it changes the derived encryption keys and can make existing encrypted fields, including user email lookups, unreadable. - For additional security, set custom encryption keys via
ACTIVE_RECORD_ENCRYPTION_*variables - If you enable custom keys on an existing self-hosted instance, run
bin/rails security:backfill_encryptiononce to rewrite older plaintext values - If users suddenly see “invalid username or password” after encryption changes, restore the previous
SECRET_KEY_BASEor previousACTIVE_RECORD_ENCRYPTION_*values first, then rerun the backfill task if you intentionally moved to dedicated keys.
TOTP one-time use
Each TOTP code is accepted only once. When a user signs in with a code, Sure records the time step of that code and rejects any subsequent use of the same step—including concurrent requests that arrive at the same time. A code seen over the shoulder, captured by a proxy, or relayed by a phishing page cannot be replayed within its validity window. The time step is claimed atomically with a conditional database update, so two simultaneous requests using the same code can never both succeed. Setting up or disabling two-factor authentication clears the recorded time step.Issuer validation
- OIDC identities store the issuer claim from ID token
- On subsequent logins, issuer is verified against configured provider
- Prevents issuer impersonation attacks
Admin access
- SSO provider management requires
super_adminrole - Regular
adminusers (family admins) cannot access/admin/sso_providers - All provider changes logged with user ID
Log filtering
Sure filters sensitive values from request logs so they never appear in log output, even when verbose parameter logging is on. The following parameters are always redacted:- Passwords, tokens, keys, and secrets (standard Rails defaults)
- One-time codes: MFA TOTP codes, backup codes, OAuth and bank authorization codes, and the desktop SSO exchange code (the
codeparameter, anchored —currency_code,country_code, andpostal_coderemain readable) - Mobile SSO linking code (
linking_code) and invitation code (invite_code) - SimpleFIN access URL (
access_url) - Device authorization flow fields (
device_code,user_code,verification_uri_complete) - FinanceKit publisher credential and event fields
config/initializers/filter_parameter_logging.rb.
Rate limiting
Sure uses Rack::Attack to throttle credential-checking endpoints in production and staging. Rate limiting is disabled in development and test environments to avoid flakiness. Every endpoint that checks a password, TOTP code, or backup code is throttled by both IP address and a credential-identifying discriminator (email address, or the session-bound user ID for MFA step-up). Both throttles must pass — an attacker cannot bypass one by rotating IPs against a single target or by spraying many addresses from one IP./sessions.json) so scripted clients cannot bypass it by appending a file extension.
For JSON API requests (Content-Type: application/json), the email discriminator is extracted from the request body before Rails parses parameters. The body is rewound after reading so the controller still receives it intact. Non-rewindable input streams (Rack 3 servers that do not support rewind) skip the email throttle and fall back to IP-only throttling for those requests.
The password-change throttle uses the signed-in user’s ID (resolved from the session cookie) rather than an email address, since the endpoint requires an active session. Requests without a valid session are redirected to sign in and do not spend either budget. During an admin impersonation, the throttle is keyed on the impersonated user’s ID — the same user whose password is being checked — so the impersonating admin’s sessions do not gain extra guesses.
Example configurations
Default hybrid (local + SSO)
Pure SSO-only
SSO-only with emergency admin override
Link-only JIT + restricted domains
Advanced features
Request signing (SAML)
Generate key pair:- Toggle “Sign requests” to enabled
- Paste private key content
- Certificate automatically included in SP metadata
Custom attribute mapping
Map custom IdP attributes to application fields:Conditional role assignment
Assign roles based on multiple conditions:Role hierarchy
Define role hierarchies for automatic dependent roles:Best practices
Use OIDC when available
Use OIDC when available
Enable database-backed providers
Enable database-backed providers
Implement role mapping
Implement role mapping
Monitor audit logs
Monitor audit logs
Rotate secrets regularly
Rotate secrets regularly
Test before enabling
Test before enabling