import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
SAML 2.0 Single Sign-On Configuration
Tier: Enterprise
Stirling-PDF supports SAML 2.0 Single Sign-On for enterprise deployments. This allows integration with Identity Providers (IdP) like Okta, Azure AD, Google Workspace, OneLogin, Authentik, and others.
Looking for OAuth 2.0 SSO? See OAuth SSO Configuration (Server tier).
Prerequisites
Before starting, ensure you have:
- [ ] Enterprise license active - SAML requires Enterprise tier
- [ ] Configs directory mounted - Docker volume mounted (e.g.,
./configs:/configs:ro) - [ ] Public backend URL configured - Set
system.backendUrlto your public backend API URL (often same as frontend, verifyhttps://your-domain.com/api/v1/info/statusis accessible) - [ ] Reverse proxy configured - Nginx/Traefik/Caddy with X-Forwarded-* headers forwarding
- [ ] Login enabled -
security.enableLogin: truein settings - [ ] Admin account ready - Either existing admin or plan to use
security.initialLogincredentials - [ ] IdP admin access - Access to your SAML Identity Provider (Okta, Azure AD, etc.)
â ī¸ License Requirement: SAML 2.0 authentication requires an ENTERPRISE license. Existing users created before SAML was license-gated are grandfathered and can continue using SAML with any license tier.
đĄ Tip: Start with
loginMethod: allduring initial setup to allow both username/password and SAML login. This ensures you can always access the admin account if SAML configuration needs adjustment.
Setup Guide
Follow these steps in order to configure SAML SSO:
Step 1: Setup Certificates
SAML requires 3 certificate files for mutual trust:
| Certificate | Purpose | Action |
|---|---|---|
| SP Private Key | Sign SAML requests to IdP | Generate with OpenSSL |
| SP Certificate | Prove identity to IdP | Generate with OpenSSL, upload to IdP |
| IdP Certificate | Verify SAML responses from IdP | Download from your IdP |
1a. Generate Service Provider (SP) Keypair
Stirling-PDF needs a keypair to sign SAML requests and verify responses.
âšī¸ If you don't have a keypair, generate one using OpenSSL:
openssl req -newkey rsa:2048 -nodes \ -keyout private_key.key \ -x509 -days 365 \ -out certificate.crt \ -subj "/C=US/ST=State/L=City/O=Stirling-PDF/CN=your-domain.com"Command explanation: -
rsa:2048: Generates 2048-bit RSA key (secure standard) --nodes: No passphrase (required for automated systems) --days 365: Certificate valid for 1 year - Creates two files:private_key.key(private) andcertificate.crt(public)
If you already have a keypair, ensure you have both the private key and certificate files ready.
1b. Download IdP Certificate
- Go to your IdP admin panel
- Find SAML app/provider settings
- Download signing certificate (PEM format)
- Save as
idp-certificate.pem
1c. Place Certificates in Mounted Directory
Place all 3 certificates inside your mounted configs directory:
./configs/
âââ private_key.key â SP private key (keep secure!)
âââ certificate.crt â SP certificate (will upload to IdP)
âââ idp-certificate.pem â IdP certificate (downloaded)
â ī¸ Critical: Use absolute paths in configuration:
/configs/filename.pem(nofile:orclasspath:prefix for Docker)
Step 2: Configure Stirling-PDF
Configure SAML authentication by providing:
- IdP URLs and certificate - Get these from your Identity Provider (obtained from IdP admin panel)
- SP certificates - Point to the certificate files created in Step 1
- Backend URL - Your public backend API URL for SAML callbacks (often same as frontend, e.g., https://stirling.example.com)
- Login settings - Enable login and set method to all (allows both username/password and SAML during setup)
Key configuration options:
- autoCreateUser: true - Automatically create user accounts on first SAML login
- blockRegistration: false - Allow new SAML users (set to true to require admin pre-approval)
- registrationId: stirling - Identifier used in SAML URLs (must match across all URLs)
/configs/settings.yml:
```yaml
security:
enableLogin: true
loginMethod: all # Keep 'all' during initial setup
saml2:
enabled: true
autoCreateUser: true
blockRegistration: false
registrationId: stirling
# Identity Provider (IdP) URLs (get from your IdP)
idpSingleLoginUrl: https://idp.example.com/saml/login
idpSingleLogoutUrl: https://idp.example.com/saml/logout
idpIssuer: https://idp.example.com/entityid
idpCert: /configs/idp-certificate.pem
# Service Provider (SP) Certificates
privateKey: /configs/private_key.key
spCert: /configs/certificate.crt
# Required for SAML callback URLs
system:
backendUrl: https://stirling.example.com
```
docker-compose.yml or Docker run command:
```yaml
environment:
SYSTEM_BACKENDURL: https://stirling.example.com
SECURITY_ENABLELOGIN: true
SECURITY_LOGINMETHOD: all
SECURITY_SAML2_ENABLED: true
SECURITY_SAML2_AUTOCREATEUSER: true
SECURITY_SAML2_BLOCKREGISTRATION: false
SECURITY_SAML2_REGISTRATIONID: stirling
SECURITY_SAML2_IDPSINGLELOGINURL: https://idp.example.com/saml/login
SECURITY_SAML2_IDPSINGLELOGOUTURL: https://idp.example.com/saml/logout
SECURITY_SAML2_IDPISSUER: https://idp.example.com/entityid
SECURITY_SAML2_IDPCERT: /configs/idp-certificate.pem
SECURITY_SAML2_PRIVATEKEY: /configs/private_key.key
SECURITY_SAML2_SPCERT: /configs/certificate.crt
```
đĄ Tip: Replace the example URLs (
idp.example.com) with actual values from your Identity Provider.
Additional Configuration: baseUrl for SAML SLO
For Single Logout (SLO) to work correctly in production, you must also set the baseUrl property:
/configs/custom_settings.yml:
```yaml
baseUrl: "https://your-domain.com"
```
```yaml
environment:
baseUrl: "https://your-domain.com"
```
â ī¸ Important: Both
system.backendUrlandbaseUrlshould be set to your public-facing URL for SAML to work correctly in production.
Step 3: Configure Your Identity Provider
Provide your IdP with these Service Provider details:
Entity ID / SP Metadata URL:
Assertion Consumer Service (ACS) URL:
Single Logout (SLO) URL:
đ Important: Replace
stirlingwith yourregistrationIdvalue if you changed it. The registration ID must match in all URLs.
Upload SP Certificate to IdP (Critical Step):
1. Open certificate.crt (your SP public certificate)
2. In your IdP's SAML app configuration, find "Verification Certificate" or "SP Certificate" field
3. Upload or paste certificate.crt contents
4. Save IdP configuration
Without uploading the SP certificate, your IdP cannot verify requests from Stirling-PDF.
Configure NameID and Attributes:
- NameID format: email or unspecified
- Ensure at least one username attribute is sent: username, emailaddress, name, upn, or uid
Step 4: Test SAML Login
- Open an incognito/private browser window
- Navigate to
https://your-domain.com - Click "Login via Single Sign-On" button
- You'll be redirected to your IdP login page
- Enter your IdP credentials
- You'll be redirected back to Stirling-PDF
- A new user account is automatically created (if
autoCreateUser: true)
â ī¸ If login fails, check application logs for SAML errors. See Troubleshooting section.
Step 5: Promote SAML User to Admin
- Log in with your initial admin account (username/password)
- Go to Settings â User Management
- Find the SAML user account (created during test login)
- Change Role to Admin
- Save
â ī¸ Important: Keep at least one SAML user with admin privileges before switching to SSO-only mode.
Step 6 (Optional): Switch to SSO-Only Mode
Once you've verified SAML works and have a SAML admin user:
Restart Stirling-PDF.
Configuration Reference
Required Properties
| Property | Description | Example |
|---|---|---|
security.saml2.enabled |
Enable SAML 2 authentication | true |
security.saml2.idpSingleLoginUrl |
IdP's Single Sign-On URL | https://idp.example.com/sso |
security.saml2.idpSingleLogoutUrl |
IdP's Single Logout URL | https://idp.example.com/slo |
security.saml2.idpIssuer |
IdP's Entity ID / Issuer | https://idp.example.com |
security.saml2.idpCert |
IdP's signing certificate (PEM format) | /configs/idp-cert.pem |
security.saml2.privateKey |
Your SP private key | /configs/private_key.key |
security.saml2.spCert |
Your SP certificate | /configs/certificate.crt |
system.backendUrl |
Public HTTPS URL for callbacks | https://stirling.example.com |
Optional Properties
| Property | Default | Description |
|---|---|---|
security.saml2.autoCreateUser |
false |
Auto-create users on first SAML login |
security.saml2.blockRegistration |
false |
Block new users (only allow pre-registered) |
security.saml2.registrationId |
stirling |
Registration ID (must match ACS URL path) |
security.saml2.provider |
null |
Optional provider name for logging |
security.loginMethod |
all |
Login method: all, normal, oauth2, saml2 |
Advanced Configuration
SAML Attribute Mapping
Stirling-PDF attempts to determine the username in the following priority order:
usernameattributeemailaddressattribute (or full URI:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress)nameattribute (or full URI:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name)upnattribute (User Principal Name - often used in Active Directory)uidattribute (Unix user ID)- NameID from SAML Subject (fallback if no attributes provided)
Minimum requirement: NameID in the SAML Subject (used as fallback identifier)
Recommended: At least one username attribute from the priority list above
Attribute Debugging
Enable debug logging to see what attributes your IdP is sending:
/configs/custom_settings.yml:
```yaml
logging:
level:
stirling.software.proprietary.security.saml2: DEBUG
```
bash
LOGGING_LEVEL_STIRLING_SOFTWARE_PROPRIETARY_SECURITY_SAML2=DEBUG
Check logs for:
đĄ Note: Currently, Stirling-PDF only uses attributes for username identification. Other attributes (first name, last name, groups, roles) are extracted but not used.
Understanding Registration ID
The registrationId is a critical configuration value that becomes part of your SAML URLs:
With registrationId: stirling, your URLs are:
- Metadata: https://your-domain.com/saml2/service-provider-metadata/stirling
- ACS: https://your-domain.com/login/saml2/sso/stirling
If you change the registration ID:
Your URLs become:
- Metadata: https://your-domain.com/saml2/service-provider-metadata/mycompany
- ACS: https://your-domain.com/login/saml2/sso/mycompany
â ī¸ Critical: If you change
registrationIdafter configuring your IdP, you must update ALL URLs in your IdP configuration. The registration ID must match exactly in all places, or SAML login will fail.đĄ Recommendation: Keep the default
stirlingvalue unless you have a specific reason to change it (e.g., running multiple Stirling-PDF instances with the same IdP).
Auto-Login Feature
Tier: Enterprise
Automatically redirect users to SAML login, bypassing the Stirling-PDF login screen:
Behavior:
- Users accessing Stirling-PDF are immediately redirected to IdP
- After 5 failed attempts (configurable via security.loginAttemptCount), auto-redirect is disabled
- Users can still manually access /login for form login if loginMethod: all
Troubleshooting
"SAML requires Enterprise license"
Cause: SAML authentication requires Enterprise tier license.
Solution:
- Verify valid Enterprise license is configured
- Check premium.enabled=true in settings
- Existing users created before license enforcement are grandfathered
"Invalid SAML response signature"
Cause: IdP certificate mismatch or incorrect format.
Solution:
- Verify idpCert file matches certificate from IdP
- Ensure certificate is in PEM format (starts with -----BEGIN CERTIFICATE-----)
- Re-download certificate from IdP
- Check certificate hasn't expired
"ACS URL mismatch"
Cause: Redirect URL doesn't match IdP configuration.
Solution:
- Verify SYSTEM_BACKENDURL is set to public HTTPS URL
- Check reverse proxy sends X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Port headers
- Ensure registrationId matches in both URL and configuration
- Update ACS URL in IdP to match: https://your-domain.com/login/saml2/sso/stirling
"File not found: idp-certificate.pem"
Cause: Certificate file path is incorrect.
Solution:
- Verify file exists at specified path
- For Docker: ensure volume is mounted correctly
- Use absolute paths like /configs/filename.pem (no file: prefix)
- Check file permissions (must be readable by application)
"Cannot auto-create user"
Cause: User doesn't exist and auto-creation is disabled.
Solution:
- Set autoCreateUser: true to allow new users
- Or pre-create user accounts as admin
- Check license allows additional users
"Redirect loop after SAML login"
Cause: Session or cookie issues.
Solution:
- Clear browser cookies
- Check SYSTEM_BACKENDURL matches actual access URL
- Verify cookies are allowed for domain
- Ensure SameSite cookie settings are compatible
"Invalid username" error
Cause: No valid username found in assertion.
Solution:
1. Enable debug logging to see what attributes are received
2. Ensure IdP sends at least one of: username, emailaddress, name, upn, uid
3. Verify NameID is present in SAML Subject as fallback
4. Check attribute name format (short name vs full URI)
Debug Logging
Enable SAML debug logging to see detailed authentication flow:
/configs/custom_settings.yml:
```yaml
logging:
level:
org.springframework.security.saml2: DEBUG
org.opensaml: DEBUG
stirling.software.proprietary.security: DEBUG
```
bash
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY_SAML2=DEBUG
LOGGING_LEVEL_ORG_OPENSAML=DEBUG
LOGGING_LEVEL_STIRLING_SOFTWARE_PROPRIETARY_SECURITY=DEBUG
Check logs for SAML attribute information:
Inspect SAML Assertions
Use browser developer tools:
1. Open Network tab
2. Clear network log
3. Attempt SAML login
4. Look for POST to /login/saml2/sso/stirling
5. Decode SAMLResponse parameter (Base64 + inflate)
Tools: - SAML-tracer (Firefox/Chrome extension) - SAML Decoder (online tool)
Known Limitations
idpMetadataUri Not Auto-Populating
The idpMetadataUri configuration field exists but is not currently used to auto-populate IdP settings. You must manually configure:
- idpSingleLoginUrl
- idpSingleLogoutUrl
- idpIssuer
- idpCert
Workaround: Manually extract values from IdP metadata XML.
đĄ Note: Auto-populating IdP settings from metadata URI is a planned enhancement coming soon.
See Also
- OAuth SSO Configuration - OAuth 2.0 / OIDC setup
- System and Security - Additional security settings
- External Database - User storage configuration
- Paid Offerings - Enterprise tier and licensing information