x
Skip to main content

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.backendUrl to your public backend API URL (often same as frontend, verify https://your-domain.com/api/v1/info/status is accessible)
  • Reverse proxy configured - Nginx/Traefik/Caddy with X-Forwarded-* headers forwarding
  • Login enabled - security.enableLogin: true in settings
  • Admin account ready - Either existing admin or plan to use security.initialLogin credentials
  • 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: all during 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:

CertificatePurposeAction
SP Private KeySign SAML requests to IdPGenerate with OpenSSL
SP CertificateProve identity to IdPGenerate with OpenSSL, upload to IdP
IdP CertificateVerify SAML responses from IdPDownload 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) and certificate.crt (public)

If you already have a keypair, ensure you have both the private key and certificate files ready.

1b. Download IdP Certificate​

  1. Go to your IdP admin panel
  2. Find SAML app/provider settings
  3. Download signing certificate (PEM format)
  4. 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 (no file: or classpath: 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)

Edit /configs/settings.yml:

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

💡 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:

Add to /configs/custom_settings.yml:

baseUrl: "https://your-domain.com"

âš ī¸ Important: Both system.backendUrl and baseUrl should 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:

https://your-domain.com/saml2/service-provider-metadata/stirling

Assertion Consumer Service (ACS) URL:

https://your-domain.com/login/saml2/sso/stirling

Single Logout (SLO) URL:

https://your-domain.com/logout

📌 Important: Replace stirling with your registrationId value 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​

  1. Open an incognito/private browser window
  2. Navigate to https://your-domain.com
  3. Click "Login via Single Sign-On" button
  4. You'll be redirected to your IdP login page
  5. Enter your IdP credentials
  6. You'll be redirected back to Stirling-PDF
  7. 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​

  1. Log in with your initial admin account (username/password)
  2. Go to Settings → User Management
  3. Find the SAML user account (created during test login)
  4. Change Role to Admin
  5. 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:

security:
loginMethod: saml2 # Disables username/password login

Restart Stirling-PDF.

Configuration Reference​

Required Properties​

PropertyDescriptionExample
security.saml2.enabledEnable SAML 2 authenticationtrue
security.saml2.idpSingleLoginUrlIdP's Single Sign-On URLhttps://idp.example.com/sso
security.saml2.idpSingleLogoutUrlIdP's Single Logout URLhttps://idp.example.com/slo
security.saml2.idpIssuerIdP's Entity ID / Issuerhttps://idp.example.com
security.saml2.idpCertIdP's signing certificate (PEM format)/configs/idp-cert.pem
security.saml2.privateKeyYour SP private key/configs/private_key.key
security.saml2.spCertYour SP certificate/configs/certificate.crt
system.backendUrlPublic HTTPS URL for callbackshttps://stirling.example.com

Optional Properties​

PropertyDefaultDescription
security.saml2.autoCreateUserfalseAuto-create users on first SAML login
security.saml2.blockRegistrationfalseBlock new users (only allow pre-registered)
security.saml2.registrationIdstirlingRegistration ID (must match ACS URL path)
security.saml2.providernullOptional provider name for logging
security.loginMethodallLogin method: all, normal, oauth2, saml2

Advanced Configuration​

SAML Attribute Mapping​

Stirling-PDF attempts to determine the username in the following priority order:

  1. username attribute
  2. emailaddress attribute (or full URI: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress)
  3. name attribute (or full URI: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name)
  4. upn attribute (User Principal Name - often used in Active Directory)
  5. uid attribute (Unix user ID)
  6. 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:

Add to /configs/custom_settings.yml:

logging:
level:
stirling.software.proprietary.security.saml2: DEBUG

Check logs for:

Extracted SAML Attributes: {username=[john.doe], emailaddress=[[email protected]], ...}

💡 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:

security:
saml2:
registrationId: stirling # Default value

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:

security:
saml2:
registrationId: mycompany # Custom value

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 registrationId after 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 stirling value 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:

premium:
proFeatures:
SSOAutoLogin: true

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:

Add to /configs/custom_settings.yml:

logging:
level:
org.springframework.security.saml2: DEBUG
org.opensaml: DEBUG
stirling.software.proprietary.security: DEBUG

Check logs for SAML attribute information:

Extracted SAML Attributes: {username=[john.doe], emailaddress=[[email protected]], ...}

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:

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​