SAML 2.0 Service Provider
Tetrapus acts as a SAML 2.0 SP. Users hit the login page, are redirected to the configured enterprise Identity Provider (IdP), authenticate there, and the IdP returns a signed SAMLResponse to the Tetrapus ACS endpoint that mints a session.
Why SAML
Most regulated enterprises and government tenants standardise on SAML 2.0 for browser SSO. It pre-dates OIDC, has deeper attribute-mapping conventions, and is the only protocol some compliance auditors accept for sensitive workloads. Tetrapus supports it for parity with the rest of the federation surface.
SP-initiated flow
The user always starts at Tetrapus. They pick their IdP, get a 302 to the IdP's SSO endpoint with a SAMLRequest in the query string, authenticate (and complete MFA) at the IdP, and are bounced back via POST to the Tetrapus Assertion Consumer Service (ACS) URL with a signed SAMLResponse.
IdP setup walkthrough
Steps are generic across IdPs (Okta, Azure AD, ADFS, Keycloak). Substitute terminology as needed.
- Register Tetrapus as an SP. In the IdP admin console, create a new SAML 2.0 application. Set the SP entity ID to the value Tetrapus exposes at
/api/v1/saml/{id}/metadata. - Configure the ACS URL. Point the IdP at
https://<your-tetrapus>/api/v1/saml/{id}/acs. Binding:HTTP-POST. - Upload the IdP signing certificate into the Tetrapus provider record (
x509_cert_pemfield). Tetrapus verifies every assertion against this exact key. - Map attributes. Configure the IdP to release at minimum an email attribute. Optionally release given_name, family_name, groups.
- Pre-provision users. Either via SCIM (auto) or by setting
saml_subjecton each user record manually. JIT user creation is not enabled by default. - Test SP-initiated start by visiting
/api/v1/saml/{id}/sso-startdirectly in a browser.
saml_providers schema
CREATE TABLE saml_providers (
id TEXT PRIMARY KEY, -- ULID
org_id TEXT NOT NULL REFERENCES orgs(id),
name TEXT NOT NULL, -- "Acme Okta"
entity_id TEXT NOT NULL, -- IdP entity ID
sso_url TEXT NOT NULL, -- IdP SingleSignOnService
slo_url TEXT, -- Optional SingleLogoutService
x509_cert_pem TEXT NOT NULL, -- IdP signing cert
name_id_format TEXT NOT NULL DEFAULT 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
attr_mapping TEXT NOT NULL, -- JSON AttributeMapping
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE (org_id, name)
); AttributeMapping
Tells Tetrapus which SAML attribute to read for each user field. JSON-serialised in the
attr_mapping column. The defaults below
work for Okta and Azure AD's standard claim sets.
{
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"given_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
"family_name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
"groups": "http://schemas.xmlsoap.org/claims/Group",
"name_id_as_subject": true
} NameID & Single Logout
The NameID from the assertion is stored
on the user record as saml_subject and is the
primary lookup key on subsequent logins — the email attribute is only used at provisioning time.
Single Logout (SLO) is best-effort: if the IdP defines a slo_url,
Tetrapus will POST a LogoutRequest there when the user signs out, then revoke the local session regardless
of the IdP response.
Status — Hardening notes
Tetrapus verifies: RSA-SHA256 signature on the SAMLResponse (or on the inner Assertion), audience restriction matches our entity ID, and NotOnOrAfter / NotBefore bounds. What's not implemented yet: full xml-exc-c14n canonicalisation per the spec — we do a constrained text-normalisation that handles the IdPs in our test matrix. ECDSA-signed responses, encrypted assertions, and IdP-initiated unsolicited responses are also deferred. Pre-provisioning is required: there is no JIT user creation in the SAML path today.
Related
- SAML Admin & API reference
- SCIM 2.0 — auto-provision users instead of manual
saml_subjectsetting - WebAuthn — local MFA on top of SAML
- ← Federation overview
Questions?
Reach out for help with integration, deployment, or custom domain codecs.