Single sign-on: SAML 2.0, OIDC and group-based roles
Connect your own identity provider on the Enterprise plan — service-provider values, step-by-step Okta, Entra ID and Google Workspace setup, the attribute reference, mapping directory groups to PulseTrace roles, verified domains, certificate rollover and troubleshooting.
Enterprise organizations authenticate their people against their own identity provider over SAML 2.0 or OIDC, with roles driven by directory groups. Configure it under Developer & API → Single Sign-On (owner or admin).
Service provider values
These identify PulseTrace to your IdP. They are the same for every connection and never change; the settings screen shows them with a copy button.
| Field | Value |
|---|---|
| Entity ID / Audience / Identifier | https://dash.pulsetrace.app/api/v1/auth/sso/metadata |
| ACS URL / Reply URL / Single sign-on URL | https://dash.pulsetrace.app/api/v1/auth/sso/acs |
| Metadata XML | https://dash.pulsetrace.app/api/v1/auth/sso/metadata |
| OIDC redirect URI | https://dash.pulsetrace.app/api/v1/auth/sso/oidc/callback |
| NameID format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress |
| Binding | HTTP-POST |
| Signature | Assertions must be signed. Response signing is optional. |
Our signing certificate is self-signed and lives for five years. In SAML the service-provider certificate is a key carrier, not a trust anchor — your IdP trusts it because an administrator pasted it in, so a CA-issued certificate would add an expiry someone else controls and nothing else.
Attribute reference
PulseTrace reads four things from an assertion. Only the first is required.
| What | SAML — attribute Name or FriendlyName | OIDC — claim | Required |
|---|---|---|---|
email, emailAddress, mail, urn:oid:0.9.2342.19200300.100.1.3, or the NameID when it is an address | email (with email_verified true) | Yes | |
| Stable identifier | the NameID | sub | Yes |
| Display name | name, displayName, cn, commonName | name | No — falls back to the email |
| Groups | whatever you name in Group attribute | whatever you name in Group attribute | No — only for group-based roles |
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress matches emailaddress without you having to know which form your IdP sends.The stable identifier matters more than it looks. Users are matched on it, not on email, so renaming someone in your directory does not create a second PulseTrace account. Prefer a NameID that never changes — in Entra ID that is the object ID, not the UPN, if your people's addresses change.
Mapping directory groups to roles
Without this, everyone provisioned through a connection receives the same role. With it, your directory decides who is an admin.
- 1Make your IdP release the group claim — this is a separate step in every provider, and the single most common reason mapping appears not to work. See the per-provider sections below.
- 2In Group attribute, enter the attribute or claim name exactly as your IdP sends it.
- 3Add one mapping row per group, choosing Admin, Developer or Viewer.
- 4Optionally turn on Re-apply roles on every sign-in.
| Rule | Behaviour |
|---|---|
| Several groups match | The highest role wins — admin beats developer beats viewer. Order in the form does not matter. |
| No group matches | The connection's default role. An unmapped group is never an error, so a new group in your directory cannot lock anyone out. |
| Group names | Matched exactly, but case-insensitively and ignoring surrounding whitespace. PT-Admins matches pt-admins; pt-admins-eu does not. |
| Multi-valued groups | A SAML attribute with several AttributeValue elements is read in full. An OIDC claim may be a JSON array, or a comma/semicolon-separated string. |
| Owner | Never assignable. No group can grant ownership — transfer it deliberately under Organization → Users. |
Group attribute: groups platform-admins -> Admin backend -> Developer frontend -> Developer support -> Viewer Default role: Viewer Re-apply on sign-in: on A person in [backend, platform-admins] -> Admin (highest wins) A person in [frontend] -> Developer A person in [finance] -> Viewer (default; no match)
Okta
- 1Applications → Create App Integration → SAML 2.0.
- 2Single sign-on URL: the ACS URL above. Audience URI: the Entity ID above.
- 3Name ID format EmailAddress, application username Email.
- 4Attribute Statements:
email→user.email,name→user.displayName. - 5Group Attribute Statements: name
groups, filter Matches regex.*(or a narrower regex — releasing every group of a large directory makes assertions needlessly large). - 6On the Sign On tab, View SAML setup instructions gives you the Identity Provider Single Sign-On URL, the Issuer, and the X.509 certificate. Paste those three into PulseTrace.
- 7Assign the app to the people or groups who should have access. Group attribute
groups.
Microsoft Entra ID (Azure AD)
- 1Enterprise applications → New application → Create your own → Integrate any other application.
- 2Single sign-on → SAML. Identifier (Entity ID) and Reply URL are the two values above.
- 3Under Attributes & Claims, the unique user identifier should be a value that does not change — the object ID is safer than the UPN if addresses change. Add a claim named
email. - 4Add a group claim: choose which groups to emit, and set Source attribute to *Group ID* (object GUIDs) or *sAMAccountName*/*Group Name* if you have synchronised on-premises groups.
- 5Download the Certificate (Base64) and copy the Login URL and Microsoft Entra Identifier. Paste those into PulseTrace.
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups, and by default its values are object GUIDs, not names. Either paste the GUIDs into the mapping rows, or configure the claim to emit group names first. A mapping that silently matches nothing is nearly always this.Google Workspace
- 1Admin console → Apps → Web and mobile apps → Add app → Add custom SAML app.
- 2Copy the SSO URL, Entity ID and Certificate from Google's screen — those are the three PulseTrace needs.
- 3ACS URL and Entity ID: the two values above. Name ID format EMAIL, Name ID Basic Information → Primary email.
- 4Attribute mapping: Primary email →
email, First/Last name →name. - 5For groups, add a Group membership mapping with the app attribute named
groups, selecting the groups to release. - 6Turn the app ON for everyone, or for the organizational units that should have access.
OIDC (any provider)
- 1Create a confidential web application with the redirect URI
https://dash.pulsetrace.app/api/v1/auth/sso/oidc/callback. - 2Grant the
openid,emailandprofilescopes — plus whatever scope your provider requires to release groups (groupson Okta and Keycloak, an optional claim on Entra). - 3Paste the issuer (the base URL whose
/.well-known/openid-configurationyour provider publishes), the client ID and the client secret. - 4If you want group-based roles, set Group attribute to the claim name, usually
groups.
Only the authorization-code flow with PKCE and a nonce is supported; implicit and hybrid are not. The email_verified claim must be true — if your provider does not vouch for the address, neither can we, because the address is what the domain claim is checked against.
Verified domains
A connection only accepts sign-ins for addresses at a domain you have listed and verified. Verification is the same DNS check used elsewhere in PulseTrace (Monitors → Domain verification), so a domain you have already verified needs nothing further.
- A claim on
example.comalso coversalice@eng.example.com— owning the domain is what lets you speak for everything beneath it. - A domain can be claimed by one organization. If yours is already taken, contact us rather than retrying.
- If the verification check cannot be completed, sign-in is refused rather than allowed. It fails closed on purpose.
What happens on first sign-in
- 1The person enters their work email at Sign in with SSO. The address only selects which provider to send them to; the assertion decides who they are.
- 2We check the email's domain is claimed by the connection and verified.
- 3An existing PulseTrace account on the same address, in the same organization, is linked — monitors, keys and history are untouched. Otherwise a new member is created.
- 4The role comes from the group mapping, or the default role if nothing matches.
- 5Two-factor authentication, if your organization requires it, still applies.
Certificate rollover
A lapsed IdP signing certificate breaks sign-in for everyone at once, with an error from the IdP that says nothing useful. It is the most common way enterprise SSO fails.
- A connection holds a list of certificates. Add the new one alongside the old before your IdP switches, then remove the old one — both are accepted meanwhile, so there is no flag day.
- The settings screen warns 30 days before expiry and says plainly when one has expired.
- Certificates may be pasted as PEM (with the BEGIN/END lines) or as the bare base64 body; both are accepted and stored identically.
IdP-initiated sign-in
Off by default. An IdP-initiated response carries no InResponseTo, so it cannot be tied back to a request we made and a captured assertion cannot be distinguished from a fresh one by that means — only the assertion-ID replay cache stands in the way. Enable it only if your people genuinely start from a tile in the IdP dashboard.
Troubleshooting
Sign-in failures are deliberately generic in the browser — a page that reports which check failed is a probing oracle. The detail is in the service logs. The common causes, in the order they occur:
| Symptom | Usual cause |
|---|---|
| Everyone is bounced back to the sign-in page immediately | The email's domain is not listed on the connection, or not verified. Check both under the connection and under Monitors → Domain verification. |
| It worked, then stopped for everyone on the same day | The IdP signing certificate expired or was rotated. Add the new certificate; the screen warns 30 days ahead. |
| “Another connection is already enabled” | Only one connection can be live at a time. Disable the old one before enabling the new — both can exist while you migrate. |
| Everyone gets the default role, group mapping seems ignored | The IdP is not releasing the group claim, or the attribute name does not match, or (on Entra) the values are object GUIDs and the mappings use names. |
| One person keeps the wrong role | Re-apply roles on every sign-in is off, so the role was set once at provisioning. Turn it on, or change the role under Organization → Users. |
| An owner is not being demoted by their group | Deliberate. An owner's role is never changed by SSO. |
| “That domain is already claimed” | Another organization has claimed it. Contact us — this is not something to work around. |