04.04 Configuring SAML SSO
Set up SAML 2.0 single sign-on against an external identity provider — configure metadata, attribute mapping, certificate handling, and the test-before-enforcing workflow for safe rollout.
Requires: Authentication Extra
SAML 2.0 single sign-on is provided by the Authentication Extra. Core SimpleRisk supports local username/password and API key authentication only. The Extra appears on the Configure → Extras list as Custom Authentication but the management page renders as Custom Authentication Extra — same Extra, two names. See The Authentication Extra Overview for the wider picture.
Why this matters
Organizations that grow past their first ten SimpleRisk users hit the same pair of pain points: passwords nobody rotates, and accounts nobody disables when the holder leaves. SAML SSO solves both. Authentication moves to the IdP you already run for the rest of the corporate stack (Okta, Microsoft Entra ID, Google Workspace, ADFS, OneLogin), and SimpleRisk inherits its password policy, MFA enforcement, and offboarding behavior. When IT disables a leaver's IdP account on a Friday, that account stops logging into SimpleRisk on Monday. No second list to maintain.
NIST SP 800-63 Digital Identity Guidelines and SOC 2's Common Criteria 6.1 both expect an identity lifecycle: provisioned on hire, MFA-protected, deprovisioned on termination, reviewed periodically. Federating SimpleRisk onto the IdP is auditable; maintaining the lifecycle in twelve apps in parallel is theatre.
Prerequisites
- The Authentication Extra activated under Configure → Extras → Custom Authentication. Activation auto-generates a per-install SP certificate and a SimpleSAMLphp
secretsalt; both are reused across upgrades. - An admin SimpleRisk account. The configuration page is gated by the
adminpermission. - Admin access to the IdP you intend to federate with, with rights to register a new SAML application.
- A test user with a working local SimpleRisk password. This is the lockout-prevention key. SimpleRisk doesn't replace the local login form when SAML is on — both auth paths run side-by-side — but if you accidentally disable a misconfigured admin account, or treat the SSO link as your only entry point, you're stranded. Keep at least one human's local password working until the round-trip is confirmed end-to-end.
- An answer to "what role and team should new users land in?" if you intend to use just-in-time (JIT) provisioning. Without sensible defaults, JIT creates a thousand SimpleRisk accounts with read-only access and no team, and you spend the next month fixing them.
Step-by-step
1. Open the SAML configuration tab
Sign in as an admin and go to Configure → Extras. The list shows Custom Authentication with a Yes/No link in the right column — click it to open the management page (titled Custom Authentication Extra in the breadcrumb). Three tabs sit at the top: Settings, LDAP, SAML. Open the SAML tab.
2. Capture the SP metadata SimpleRisk hands to your IdP
The first card on the SAML tab is Service Provider (SP). It shows the SP entity ID / metadata URL, the SP certificate status, and a Download SP Metadata button. The metadata URL is derived from the SimpleRisk Base URL setting and looks like:
https://
/vendor/simplesamlphp/simplesamlphp/public/module.php/saml/sp/metadata.php/default-sp
If SimpleRisk Base URL isn't set or is wrong, fix it first (in Configure → Settings); every SAML round-trip depends on it. Click Download SP Metadata to save the XML, or copy the URL — most modern IdPs accept either form.
The SP name field defaults to default-sp and is part of the metadata URL. Leave the default unless you need multiple SP registrations against the same IdP. Changing the SP name after the IdP is configured invalidates the trust and forces a re-upload.
3. Register SimpleRisk as an application at your IdP
This half of the round-trip happens outside SimpleRisk. The pattern is consistent across IdPs: create a new SAML 2.0 application, upload SimpleRisk's SP metadata, then capture the IdP's metadata URL or XML for the next step.
A few IdP-specific notes:
- Okta — upload the SP metadata XML rather than entering ACS URL and audience by hand; the round-trip is more reliable that way.
- Microsoft Entra ID / ADFS — both reject AuthnRequests that include the
element. You must tick Disable scoping (ADFS / Entra ID compatibility) in step 6. This is the single most common Entra-with-SimpleRisk gotcha. - Google Workspace — set NameID format to Email address in step 4 and match SimpleRisk usernames to the IdP-side primary email.
Whichever IdP you're using, copy its SAML metadata URL (or download the XML) before moving on.
4. Paste IdP metadata back into SimpleRisk
In the Identity Provider (IdP) card, pick a Metadata source:
- Fetch from URL — paste the IdP's metadata URL into Metadata URL. SimpleRisk re-fetches on the schedule set by Metadata cache TTL (seconds) (default 3600). When the URL is unreachable on refresh, the cached copy keeps working. Use Clear cached metadata now to force the next login to re-fetch.
- Paste XML — paste the IdP's metadata XML directly. Useful when the IdP doesn't expose a public metadata URL.
- Upload XML file — same, from a file. SimpleRisk validates well-formedness and rejects DOCTYPE declarations as XXE hardening.
Set NameID format to match what the IdP issues. Let IdP decide (recommended) is the right starting point. Email address suits Google Workspace; Persistent is the right choice when you want SimpleRisk to map the same user across sessions regardless of email changes. Avoid Transient unless you specifically need it — transient NameIDs change every session and force attribute-based matching instead, which the page surfaces with an inline warning when you select it.
Trusted redirect domains is a comma-separated allow-list of domains SimpleRisk accepts as post-authentication redirect targets. It defaults to sts.windows.net, login.windows.net, dev.simplerisk.com. Add any IdP-side redirect domain not on the list.
5. Map IdP attributes to SimpleRisk fields
The User Attribute Mapping card is where most setups go wrong on the first try.
- Username match — pick Authenticated username (NameID) when the IdP's NameID is the SimpleRisk username. Pick Authenticated attribute when SimpleRisk should look at a specific SAML attribute instead (required for Transient NameID, or any opaque NameID). When you pick the attribute path, the Username attribute field appears — fill in the attribute name (commonly
mail,uid,userPrincipalName, orsAMAccountName; the field has a datalist). - Display name attribute, Email attribute, Manager username attribute — the SAML attribute names that populate those SimpleRisk user fields. Leave blank to skip. Names are case-sensitive:
displayNameis not the same asdisplayname. - Role attribute, Teams attribute — the SAML attribute names whose values identify which SimpleRisk role and team(s) a user belongs to. After saving, the Mapping button next to each opens a modal where you map the remote role/team names from the IdP to SimpleRisk's local roles and teams. SimpleRisk doesn't auto-create roles; the modal is where the IdP-side
engineering-adminsgroup becomes the SimpleRisk-side Engineering Admins role.
For just-in-time (JIT) provisioning, the underlying flag is AUTHENTICATION_ADD_NEW_USERS on the Settings tab. Set it (along with default role and team) before going live or you'll churn through manual user fixups.
6. Set authentication behavior
The Authentication Behavior card carries the round-trip toggles:
- Show the "Go to SSO Login Page" link on the main login page — the visible Go to SSO Login Page link on
/index.php. Leave this off until your test round-trip works. - Force authentication on every login — sends
ForceAuthn=truein every request, bypassing any existing IdP session. Useful for kiosks; otherwise leave off. - Logout terminates SimpleRisk session AND logs user out of the SAML Identity Provider (IdP) — initiates SAML Single Logout (SLO) on logout. SLO is fragile; if you see logout loops, turn this off.
- Require signed assertions — recommended on. Virtually every production IdP signs assertions.
- Disable scoping (ADFS / Entra ID compatibility) — required for Microsoft ADFS and Entra ID, which reject requests with the
element. - Sign authentication requests / Require encrypted assertions — these only appear when the SP certificate is configured (auto-generated on Extra activation). Enable each only after the IdP-side change is in place; enabling early breaks login.
Click Update to save.
7. Test the round-trip without locking yourself out
SimpleRisk doesn't ship a discrete test/enforce toggle. The pattern is structural: leave the SSO link on the main login page off during testing, drive your test user to the SSO URL directly, and only flip the link on once the round-trip works. The SSO login URL is:
https://
/extras/authentication/login.php
Hand that URL to a test user with a matching IdP account. You should see a redirect to the IdP, IdP login (or session reuse), redirect back, and a landing on the SimpleRisk reports page. The debug log captures every step — SAML user was successfully authenticated by the IdP. confirms the IdP side worked. If you don't see that line, look immediately above for SAML authentication failed: or SAML user was not authenticated by the IdP.; the message after the colon is the IdP's complaint and the starting point for debugging.
Your own admin account stays on the main login form at /index.php with its local password while you test. That's the lockout-recovery path. Don't disable that account.
8. Activate SSO for production
When the test round-trip is clean (including role and team mapping if you use them), tick Show the "Go to SSO Login Page" link on the main login page and click Update. Users visiting /index.php now see a Go to SSO Login Page link below the password fields. The local form remains visible; SimpleRisk does not have an enforce-SSO mode that hides it.
Verifying the configuration
Three signals confirm a healthy setup:
- A clean round-trip from
/extras/authentication/login.php— IdP redirect, IdP sign-in, redirect back, landed on the SimpleRisk reports page as the right user with the right role and teams. - The debug log shows
SAML user was successfully authenticated by the IdP.followed byGranting access for UID "(both at" USERNAME " ". infolevel). If you seeNot a valid SAML user in SimpleRisk.instead, either the user doesn't exist locally and JIT isn't on, or the username matching rule isn't picking up the right attribute. - The audit log records
Custom Authentication Extra was toggled on by username "in the". audit_logtable when activation happened — useful evidence in an access-management audit that the change is documented and dated.
Troubleshooting
If you're locked out by a SAML misconfiguration: SAML doesn't replace local auth in SimpleRisk. Go to
https://— the local login form is always shown, and SAML-on does not disable local password authentication. Sign in there with any local-password admin account and fix the SAML config. Database surgery on the/index.php usertable is the last resort, only needed if every local password is gone.
The handful of failure modes that drive most SAML support traffic.
-
Clock skew on assertion timestamps. SAML assertions carry
NotBefore/NotOnOrAftertimestamps signed by the IdP. SimpleRisk's host clock has to be inside that window. NTP drift of more than a few minutes produces "assertion is not yet valid" or "assertion has expired" errors. Fix the clock; never widen the tolerance. -
Certificate format issues. SAML certificates are PEM-encoded — base64 between
-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----lines. If the IdP exports DER (binary), convert it:openssl x509 -inform DER -in idp.cer -out idp.pem. Pasting raw base64 without the PEM header lines produces opaque "could not parse certificate" errors. -
Attribute mapping mismatches (case sensitivity). SAML attribute names are case-sensitive at the wire level.
mailandMailare different attributes. To see exactly what the IdP sends, enabledebuglog level temporarily and look for theSAML Attributes provided by the IdP:line — the array dump shows the attribute names verbatim. -
Circular redirect loops on Single Logout. SLO is the most fragile part of SAML. If the IdP can't process an SLO request, the user bounces, SimpleRisk re-issues, the IdP rejects again, loop. The fix is to turn off Logout terminates SimpleRisk session AND logs user out of the SAML Identity Provider (IdP). SimpleRisk-side logout still works; it just doesn't try to take down the IdP session as well.
-
Microsoft ADFS or Entra ID rejects AuthnRequests. Tick Disable scoping (ADFS / Entra ID compatibility) and retest.
-
The SP certificate is about to expire. The page surfaces a colored badge with days remaining; under 30 days it goes red. Use Regenerate to issue a fresh self-signed cert (RSA-2048, 10-year validity), then re-upload SP metadata to the IdP. Logins fail in the window between regeneration and IdP pickup — schedule the change.
Related
- The Authentication Extra Overview
- Multi-Factor Authentication
- OIDC Setup
- Local Authentication and Password Policies
Reference
- Permission required:
admin - API endpoint(s): Not exposed via the v2 API. The Authentication Extra registers
GET /authentication/version,GET /authentication/upgrade/db,GET /authentication/activate,GET /authentication/remote_mapping,POST /authentication/remote_mapping, andPOST /authentication/remote_items, but none of those configure SAML — SAML is form-only via the admin UI. - Implementing files:
simplerisk/admin/authentication.php(admin-side dispatcher: POST handlers for cache-clear and SP cert regenerate)simplerisk/extras/authentication/index.php(SAML configuration page render and form-submit handler)simplerisk/extras/authentication/login.php(SAML round-trip endpoint — the URL the SSO link points at)simplerisk/extras/authentication/upgrade.php(schema migration plus activation/deactivation logic)simplerisk/extras/authentication/includes/api.php(v2 API route registrations) - Database tables:
settings(configuration values),remote_role,remote_role_mapping,remote_team,remote_team_mapping(IdP-to-SimpleRisk role and team mapping), and the SimpleSAMLphp-managedSimpleSAMLphp_kvstore,SimpleSAMLphp_saml_LogoutStore, andSimpleSAMLphp_tableVersiontables (auto-created on enable, dropped on disable). Audit events are written toaudit_log. config_settingskeys: Metadata:SAML_METADATA_URL,SAML_METADATA_XML,SAML_METADATA_CACHE,SAML_METADATA_CACHE_EXPIRY,SAML_METADATA_CACHE_TTL
Attribute mapping:SAML_USERNAME_MATCH,SAML_DISPLAY_NAME_ATTRIBUTE,SAML_EMAIL_ATTRIBUTE,SAML_MANAGER_USERNAME_ATTRIBUTE,SAML_ROLE_ATTRIBUTE,SAML_TEAMS_ATTRIBUTE
Behavior toggles:SAML_FORCE_AUTHENTICATION,SAML_SIGN_AUTHN_REQUESTS,SAML_WANT_ASSERTIONS_SIGNED,SAML_DISABLE_SCOPING,SAML_REQUIRE_ENCRYPTED_ASSERTIONS,GO_TO_SSO_LOGIN,LOGOUT_FROM_REMOTE_SESSIONS,AUTHENTICATION_ADD_NEW_USERS,UPDATE_USER_WITH_DATA_FROM_IDP
SP identity:SAML_SP_NAME,SAML_NAMEID_FORMAT,SAML_SP_CERT,SAML_SP_KEY,SAML_SECRETSALT
Other:TRUSTED_DOMAINS