SAML SSO
Fluxbase supports SAML 2.0 Single Sign-On (SSO) for enterprise authentication. Integrate with identity providers like Okta, Azure AD, OneLogin, Google Workspace, and any SAML 2.0 compliant IdP.
Overview
Section titled “Overview”SAML SSO enables:
- Enterprise authentication - Users sign in with corporate credentials
- Centralized identity - Manage users from your IdP
- Security compliance - Meet enterprise security requirements
- Automatic provisioning - Create users on first login (optional)
Supported Identity Providers
Section titled “Supported Identity Providers”Fluxbase works with any SAML 2.0 compliant identity provider:
| Provider | Documentation |
|---|---|
| Okta | Okta SAML Setup |
| Azure AD | Azure AD SAML |
| Google Workspace | Google SAML Apps |
| OneLogin | OneLogin SAML |
| Auth0 | Auth0 SAML |
| Keycloak | Keycloak SAML |
| PingIdentity | PingIdentity SAML |
| JumpCloud | JumpCloud SSO |
Configuration
Section titled “Configuration”YAML Configuration
Section titled “YAML Configuration”auth: saml_providers: - name: okta enabled: true idp_metadata_url: "https://company.okta.com/app/xxx/sso/saml/metadata" entity_id: "https://myapp.example.com/auth/saml" acs_url: "https://myapp.example.com/api/v1/auth/saml/acs" attribute_mapping: email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" auto_create_users: true default_role: "authenticated"Configuration Options
Section titled “Configuration Options”| Option | Description | Required |
|---|---|---|
name | Provider identifier (used in URLs) | Yes |
enabled | Enable this provider | Yes |
idp_metadata_url | URL to IdP metadata XML | One of metadata_url or metadata_xml |
idp_metadata_xml | Inline IdP metadata XML | One of metadata_url or metadata_xml |
entity_id | SP Entity ID (unique identifier) | No (auto-generated) |
acs_url | Assertion Consumer Service URL | No (auto-generated) |
attribute_mapping | Map SAML attributes to user fields | No (defaults provided) |
auto_create_users | Create user on first login | No (default: true) |
default_role | Role for new users | No (default: authenticated) |
Environment Variables
Section titled “Environment Variables”For a single provider, use environment variables:
FLUXBASE_AUTH_SAML_PROVIDERS_0_NAME=oktaFLUXBASE_AUTH_SAML_PROVIDERS_0_ENABLED=trueFLUXBASE_AUTH_SAML_PROVIDERS_0_IDP_METADATA_URL=https://company.okta.com/app/xxx/sso/saml/metadataFLUXBASE_AUTH_SAML_PROVIDERS_0_AUTO_CREATE_USERS=trueEndpoints
Section titled “Endpoints”| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/saml/metadata/:provider | GET | SP metadata XML for IdP registration |
/api/v1/auth/saml/login/:provider | GET | Initiate SAML login (redirects to IdP) |
/api/v1/auth/saml/acs | POST | Assertion Consumer Service (IdP callback) |
/api/v1/auth/saml/providers | GET | List available SAML providers |
Setup Guide
Section titled “Setup Guide”Step 1: Configure Fluxbase
Section titled “Step 1: Configure Fluxbase”Add your SAML provider configuration:
auth: saml_providers: - name: corporate-sso enabled: true idp_metadata_url: "https://idp.example.com/metadata" auto_create_users: trueStep 2: Get SP Metadata
Section titled “Step 2: Get SP Metadata”Fetch Fluxbase’s Service Provider metadata:
curl https://myapp.example.com/api/v1/auth/saml/metadata/corporate-ssoThis returns XML containing:
- Entity ID
- ACS URL
- Certificate (if configured)
Step 3: Configure Your IdP
Section titled “Step 3: Configure Your IdP”Register Fluxbase as a Service Provider in your IdP:
- Entity ID:
https://myapp.example.com/auth/saml - ACS URL:
https://myapp.example.com/api/v1/auth/saml/acs - Name ID Format:
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
Step 4: Configure Attribute Mapping
Section titled “Step 4: Configure Attribute Mapping”Map your IdP’s attribute names to Fluxbase fields:
attribute_mapping: # Standard SAML claims email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
# Or custom attribute names from your IdP email: "user.email" name: "user.displayName"Step 5: Test Login
Section titled “Step 5: Test Login”# Redirect browser to initiate SAML loginopen "https://myapp.example.com/api/v1/auth/saml/login/corporate-sso?redirect_to=https://myapp.example.com/dashboard"IdP-Specific Setup
Section titled “IdP-Specific Setup”- In Okta Admin Console, go to Applications → Create App Integration
- Select SAML 2.0
- Configure:
- Single sign-on URL:
https://myapp.example.com/api/v1/auth/saml/acs - Audience URI (SP Entity ID):
https://myapp.example.com/auth/saml - Name ID format: EmailAddress
- Single sign-on URL:
- Download the IdP metadata URL from Sign On tab
- Configure Fluxbase:
auth: saml_providers: - name: okta enabled: true idp_metadata_url: "https://your-org.okta.com/app/xxx/sso/saml/metadata"Azure AD
Section titled “Azure AD”- In Azure Portal, go to Enterprise Applications → New application
- Select Create your own application → Non-gallery
- Go to Single sign-on → SAML
- Configure:
- Identifier (Entity ID):
https://myapp.example.com/auth/saml - Reply URL (ACS URL):
https://myapp.example.com/api/v1/auth/saml/acs
- Identifier (Entity ID):
- Download Federation Metadata XML
- Configure Fluxbase:
auth: saml_providers: - name: azure-ad enabled: true idp_metadata_url: "https://login.microsoftonline.com/{tenant-id}/federationmetadata/2007-06/federationmetadata.xml" attribute_mapping: email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/displayname"Google Workspace
Section titled “Google Workspace”- In Google Admin Console, go to Apps → Web and mobile apps
- Click Add App → Add custom SAML app
- Download IdP metadata
- Configure SP details:
- ACS URL:
https://myapp.example.com/api/v1/auth/saml/acs - Entity ID:
https://myapp.example.com/auth/saml
- ACS URL:
- Configure attribute mapping (email, name)
- Configure Fluxbase:
auth: saml_providers: - name: google enabled: true idp_metadata_xml: | <?xml version="1.0" encoding="UTF-8"?> <EntityDescriptor ...> <!-- Paste metadata XML here --> </EntityDescriptor>SDK Usage
Section titled “SDK Usage”TypeScript SDK
Section titled “TypeScript SDK”import { FluxbaseClient } from '@fluxbase/sdk'
const client = new FluxbaseClient({ url: 'http://localhost:8080' })
// List available SAML providersconst { data: providers } = await client.auth.getSAMLProviders()// [{ name: 'okta', sso_url: '...', enabled: true }]
// Get SAML login URLconst { data: loginUrl } = await client.auth.getSAMLLoginUrl('okta', { redirectTo: 'https://myapp.example.com/dashboard'})
// Redirect user to IdPwindow.location.href = loginUrl
// After IdP callback, user is authenticated// Session is automatically establishedconst { data: session } = await client.auth.getSession()React SDK
Section titled “React SDK”import { useSAMLProviders, useInitiateSAMLLogin} from '@fluxbase/sdk-react'
function SSOLoginButtons() { const { data: providers, isLoading } = useSAMLProviders() const initiateSAML = useInitiateSAMLLogin()
if (isLoading) return <div>Loading...</div>
return ( <div> {providers?.map(provider => ( <button key={provider.name} onClick={() => initiateSAML.mutate({ provider: provider.name, redirectTo: '/dashboard' })} > Sign in with {provider.name} </button> ))} </div> )}Handling Callback
Section titled “Handling Callback”After SAML authentication, users are redirected to your specified URL with a session established:
import { useEffect } from 'react'import { useSession } from '@fluxbase/sdk-react'import { useNavigate } from 'react-router-dom'
function SAMLCallback() { const { data: session, isLoading } = useSession() const navigate = useNavigate()
useEffect(() => { if (!isLoading && session) { // User is authenticated, redirect to dashboard navigate('/dashboard') } }, [session, isLoading])
return <div>Completing sign in...</div>}REST API
Section titled “REST API”List SAML Providers
Section titled “List SAML Providers”GET /api/v1/auth/saml/providersResponse:
{ "providers": [ { "name": "okta", "enabled": true, "sso_url": "https://company.okta.com/app/xxx/sso/saml" } ]}Initiate SAML Login
Section titled “Initiate SAML Login”GET /api/v1/auth/saml/login/:provider?redirect_to=https://myapp.example.com/dashboardRedirects to IdP with SAML AuthnRequest.
Get SP Metadata
Section titled “Get SP Metadata”GET /api/v1/auth/saml/metadata/:providerReturns SP metadata XML for IdP registration.
Attribute Mapping
Section titled “Attribute Mapping”Map SAML assertion attributes to user fields:
Default Mapping
Section titled “Default Mapping”attribute_mapping: email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" name: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"Common Attribute URIs
Section titled “Common Attribute URIs”| Attribute | Standard URI |
|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | |
| Name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name |
| Given Name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname |
| Surname | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname |
| UPN | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn |
Custom Attributes
Section titled “Custom Attributes”If your IdP uses custom attribute names:
attribute_mapping: email: "userEmail" name: "displayName" # Additional attributes stored in user_metadata department: "department" title: "jobTitle"User Provisioning
Section titled “User Provisioning”Auto-Create Users
Section titled “Auto-Create Users”When auto_create_users: true:
- User authenticates via SAML
- If user doesn’t exist, account is created
- Email and name populated from SAML attributes
- User assigned
default_role
Disable Auto-Creation
Section titled “Disable Auto-Creation”Set auto_create_users: false to require pre-existing accounts:
auth: saml_providers: - name: corporate-sso auto_create_users: false # User must exist in databaseUsers must be created via admin API or invite before SAML login works.
Linking Existing Accounts
Section titled “Linking Existing Accounts”SAML identity is linked to existing account if emails match:
-- SAML identity stored in auth.identitiesSELECT * FROM auth.identitiesWHERE provider = 'saml'AND provider_id = 'okta:user@example.com';Security
Section titled “Security”Best Practices
Section titled “Best Practices”- Use HTTPS - All SAML communication must use HTTPS
- Validate signatures - Fluxbase validates IdP signatures automatically
- Time validation - Assertions are rejected if expired
- Replay prevention - Assertion IDs are tracked to prevent reuse
- Audience validation - Assertions must be intended for your SP
Certificate Validation
Section titled “Certificate Validation”IdP certificates are extracted from metadata and used to validate assertion signatures:
# IdP certificate is automatically extracted from metadata# No manual configuration required for signature validationSession Security
Section titled “Session Security”SAML sessions are tracked:
-- View active SAML sessionsSELECT * FROM auth.saml_sessionsWHERE user_id = 'xxx'ORDER BY created_at DESC;Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”“SAML provider not found”
- Verify provider name matches configuration
- Check provider is enabled
“Failed to fetch IdP metadata”
- Verify
idp_metadata_urlis accessible - Check network connectivity
- Try using
idp_metadata_xmldirectly
“Invalid SAML assertion”
- Check clock synchronization between servers
- Verify ACS URL matches IdP configuration
- Ensure Entity ID matches in IdP and Fluxbase
“Email attribute not found”
- Check attribute mapping configuration
- Verify IdP is sending email attribute
- Check SAML assertion for actual attribute names
Debug Logging
Section titled “Debug Logging”Enable debug logging to troubleshoot SAML:
debug: trueCheck logs for:
- SAML request/response details
- Attribute extraction
- Signature validation
Testing with SAML Tracer
Section titled “Testing with SAML Tracer”Use browser extensions like SAML Tracer to inspect:
- AuthnRequest sent to IdP
- SAML Response from IdP
- Assertion attributes
Single Logout (SLO)
Section titled “Single Logout (SLO)”Single Logout (SLO) allows users to sign out from both Fluxbase and the IdP simultaneously, terminating sessions across all SSO applications.
Overview
Section titled “Overview”Fluxbase supports both:
- SP-initiated SLO - User logs out from Fluxbase, which notifies the IdP
- IdP-initiated SLO - IdP sends logout request to Fluxbase when user logs out elsewhere
Configuration
Section titled “Configuration”To enable SLO, configure SP signing keys for your SAML provider:
auth: saml_providers: - name: okta enabled: true idp_metadata_url: "https://company.okta.com/app/xxx/sso/saml/metadata" # SP signing keys for SLO (PEM-encoded) sp_certificate: | -----BEGIN CERTIFICATE----- MIICpDCCAYwCCQDU+pQ4P1eLvjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls ... -----END CERTIFICATE----- sp_private_key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy... ... -----END RSA PRIVATE KEY-----Generating SP Signing Keys
Section titled “Generating SP Signing Keys”Generate a self-signed certificate and key for signing LogoutRequests:
# Generate private keyopenssl genrsa -out sp-key.pem 2048
# Generate certificate (valid for 10 years)openssl req -new -x509 -key sp-key.pem -out sp-cert.pem -days 3650 \ -subj "/CN=myapp.example.com"
# View certificate detailsopenssl x509 -in sp-cert.pem -text -nooutSLO Endpoints
Section titled “SLO Endpoints”| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/saml/logout/:provider | GET | Initiate SP-initiated logout |
/api/v1/auth/saml/slo | POST/GET | Handle IdP-initiated logout & SP callback |
SP-Initiated Logout
Section titled “SP-Initiated Logout”When a user logs out from your application:
# Initiate SAML logout (redirects to IdP)GET /api/v1/auth/saml/logout/okta?redirect_url=https://myapp.example.com/goodbyeThe flow:
- Fluxbase generates a signed LogoutRequest
- User is redirected to IdP’s SLO endpoint
- IdP terminates the session
- IdP redirects back to Fluxbase with LogoutResponse
- User is redirected to
redirect_url
IdP-Initiated Logout
Section titled “IdP-Initiated Logout”When a user logs out from the IdP or another SP:
- IdP sends LogoutRequest to
/api/v1/auth/saml/slo - Fluxbase finds and terminates the SAML session
- All JWT tokens for the user are revoked
- Fluxbase sends LogoutResponse back to IdP
SDK Usage
Section titled “SDK Usage”// Check if user has SAML session with SLO supportconst { data } = await client.auth.signOut()
if (data.saml_logout && data.slo_url) { // Redirect to IdP for full logout window.location.href = data.slo_url} else { // Local logout only console.log('Signed out locally')}React SDK
Section titled “React SDK”import { useSignOut, useSession } from '@fluxbase/sdk-react'
function LogoutButton() { const signOut = useSignOut()
const handleLogout = async () => { const result = await signOut.mutateAsync()
if (result.saml_logout && result.slo_url) { // Full SAML SLO - redirect to IdP window.location.href = result.slo_url } else { // Local logout complete window.location.href = '/login' } }
return <button onClick={handleLogout}>Sign Out</button>}IdP Configuration for SLO
Section titled “IdP Configuration for SLO”Configure your IdP to send logout requests to Fluxbase:
Okta:
- In your SAML app, go to General → SAML Settings
- Enable Single Logout
- Set Single Logout URL:
https://myapp.example.com/api/v1/auth/saml/slo - Upload your SP certificate (from
sp_certificateconfig)
Azure AD:
- Go to Single sign-on → SAML
- Set Logout URL:
https://myapp.example.com/api/v1/auth/saml/slo
Google Workspace:
- In your SAML app settings
- Enable Signed Response
- Set Logout URL:
https://myapp.example.com/api/v1/auth/saml/slo
Graceful Degradation
Section titled “Graceful Degradation”If SLO is not available (no IdP SLO URL or missing signing keys), Fluxbase performs local logout only:
- SAML session is deleted
- JWT tokens are revoked
- User is signed out from Fluxbase
- No IdP notification (user remains logged in at IdP)
The signout response indicates this:
{ "message": "local logout successful", "saml_logout": false}Troubleshooting SLO
Section titled “Troubleshooting SLO”“SP signing key not configured”
- Add
sp_certificateandsp_private_keyto provider config - Ensure keys are valid PEM format
LogoutRequest rejected by IdP
- Verify SP certificate is registered in IdP
- Check certificate hasn’t expired
- Ensure IdP has SLO enabled
IdP-initiated logout not working
- Verify SLO URL is configured in IdP
- Check Fluxbase is accessible from IdP
- Review logs for incoming LogoutRequests
Multiple Providers
Section titled “Multiple Providers”Configure multiple SAML providers for different user groups:
auth: saml_providers: - name: corporate enabled: true idp_metadata_url: "https://corporate.okta.com/metadata" auto_create_users: true
- name: partner enabled: true idp_metadata_url: "https://partner.auth0.com/metadata" auto_create_users: false # Partners must be pre-created default_role: "partner"Frontend shows all providers:
{providers.map(p => ( <button onClick={() => loginWithSAML(p.name)}> Sign in with {p.name} </button>))}Role-Based Access Control (RBAC)
Section titled “Role-Based Access Control (RBAC)”Control which users can authenticate based on their Active Directory groups, Azure AD groups, or other SAML attributes from your identity provider.
Group-Based Access Control
Section titled “Group-Based Access Control”Restrict SAML authentication based on group membership:
auth: saml_providers: - name: azure-ad enabled: true idp_metadata_url: "https://login.microsoftonline.com/{tenant}/metadata" allow_dashboard_login: true
# RBAC configuration required_groups: - "FluxbaseAdmins" # User must be in at least ONE of these groups - "FluxbaseDevelopers"
required_groups_all: - "Verified" # User must be in ALL of these groups - "Active"
denied_groups: - "Contractors" # Reject users in ANY of these groups - "Suspended"
group_attribute: "groups" # SAML attribute containing groups (default: "groups")RBAC Rules
Section titled “RBAC Rules”Three types of group validation rules:
| Rule | Logic | Example Use Case |
|---|---|---|
required_groups | OR logic - User must be in at least ONE group | Allow admins OR editors |
required_groups_all | AND logic - User must be in ALL groups | Must be verified AND active |
denied_groups | DENY - Reject if user is in ANY of these groups | Block contractors or suspended accounts |
Execution order: Denied groups are checked first (highest priority), then required groups.
Common Group Attributes
Section titled “Common Group Attributes”Different identity providers use different SAML attribute names for groups:
| Identity Provider | Default Attribute | Alternative Attributes |
|---|---|---|
| Azure AD | http://schemas.microsoft.com/ws/2008/06/identity/claims/groups | groups (if configured) |
| Okta | groups | Custom attribute mapping |
| Google Workspace | groups | Custom schema |
| Active Directory | memberOf | http://schemas.xmlsoap.org/claims/Group |
Configure the attribute name:
group_attribute: "memberOf" # For Active DirectoryExample Configurations
Section titled “Example Configurations”Dashboard admin access (Azure AD)
Only users in IT or Admin groups can access the dashboard:
auth: saml_providers: - name: azure-ad-dashboard enabled: true idp_metadata_url: "https://login.microsoftonline.com/{tenant}/metadata" allow_dashboard_login: true allow_app_login: false required_groups: - "FluxbaseAdmins" - "IT-Team"Multi-tier access (Okta)
Admins and editors can access, but contractors are explicitly blocked:
auth: saml_providers: - name: okta-corporate enabled: true idp_metadata_url: "https://company.okta.com/metadata" allow_dashboard_login: true required_groups: - "Admins" - "Editors" denied_groups: - "Contractors" - "Guests"Strict verification (Active Directory)
Users must be in Admin group AND have valid employee status:
auth: saml_providers: - name: ad-sso enabled: true idp_metadata_url: "https://adfs.company.com/metadata" allow_dashboard_login: true required_groups: - "Domain Admins" required_groups_all: - "CN=Employees,OU=Groups,DC=company,DC=com" - "CN=Active,OU=Status,DC=company,DC=com" group_attribute: "memberOf"Error Messages
Section titled “Error Messages”When group validation fails, users see clear error messages:
"Access denied: user is member of restricted group 'Contractors'"- User in denied group"Access denied: missing required group 'FluxbaseAdmins'"- User missing a required group fromrequired_groups_all"Access denied: user must be member of one of: [Admins, Editors]"- User doesn’t have any of therequired_groups
Troubleshooting RBAC
Section titled “Troubleshooting RBAC”“Groups not being extracted”
-
Check the group attribute name:
Terminal window # View SAML assertion to see actual attribute names# Use browser developer tools or SAML Tracer extension -
Configure the correct attribute:
group_attribute: "memberOf" # Or the correct attribute name
“User has group but still rejected”
- Group names are case-sensitive:
"Admins"≠"admins" - Check for whitespace in group names
- Verify exact group name from IdP
“Azure AD not sending group names”
Azure AD can be configured to send either:
- Group UUIDs (default):
["abc123...", "def456..."] - Group names:
["FluxbaseAdmins", "Developers"]
To send group names instead of UUIDs:
- In Azure Portal, go to Enterprise Applications → Your App → Single sign-on
- Edit Attributes & Claims
- Edit the
groupsclaim - Set Source attribute to
group.displayname(instead ofgroup.objectid)
“How do I find my group names/IDs?”
Use SAML Tracer browser extension to inspect the actual SAML assertion and see the groups being sent by your IdP.
Dashboard SSO (Admin Login)
Section titled “Dashboard SSO (Admin Login)”SAML and OAuth providers can be used for dashboard admin authentication, enabling SSO-only mode where password login is disabled.
Enable Dashboard SSO
Section titled “Enable Dashboard SSO”When creating or editing an SSO provider, enable “Allow dashboard login”:
auth: saml_providers: - name: corporate-sso enabled: true idp_metadata_url: "https://company.okta.com/metadata" allow_dashboard_login: true # Enable for admin login allow_app_login: true # Also allow for app usersDisable Password Login
Section titled “Disable Password Login”Once SSO is configured for dashboard login, you can disable password authentication:
- Go to Authentication → Auth Settings in the dashboard
- Enable Disable Password Login under “Dashboard Login”
- Save settings
When enabled:
- The login page shows only SSO buttons
- Password form is hidden
- Backend rejects password login attempts
CLI SSO Login
Section titled “CLI SSO Login”With password login disabled, use the --sso flag for CLI authentication:
# SSO login (opens browser)fluxbase auth login --server https://api.example.com --sso
# Or use an API tokenfluxbase auth login --server https://api.example.com --token your-api-tokenThe CLI automatically detects when password login is disabled and initiates SSO flow.
Emergency Recovery
Section titled “Emergency Recovery”If you’re locked out due to misconfigured SSO, set the environment variable to bypass the setting:
FLUXBASE_DASHBOARD_FORCE_PASSWORD_LOGIN=trueThis temporarily re-enables password login regardless of the database setting.
Security Considerations
Section titled “Security Considerations”- Require at least one SSO provider - Cannot disable password login without configured SSO
- Test SSO login first - Verify SSO works before disabling passwords
- Document recovery procedures - Ensure administrators know about the env var override
- Audit SSO provider changes - Monitor for accidental removal of SSO providers
Next Steps
Section titled “Next Steps”- Authentication - Authentication overview
- OAuth Providers - Social login configuration
- Row-Level Security - Data access control