Single Sign-On (SAML)
Autoheal supports SAML 2.0 single sign-on against any compliant identity provider — Okta, Microsoft Entra ID, PingOne, OneLogin, Google Workspace, or an in-house IdP. Administrators configure it from the app.
In SAML terms Autoheal is the service provider (SP) and your identity provider is the IdP. Autoheal never receives your users' passwords or MFA factors.
An SSO connection is one link between your Autoheal organization and one IdP application. An organization can hold several — for example, during a migration between providers, or when a subsidiary authenticates elsewhere.
Setting up SSO requires the Admin role. See Roles & Permissions.
Authentication model
Autoheal reads exactly one value from your IdP: the user's email address. Roles, permissions, and integration access are determined in Autoheal, keyed on that email.
Set up a connection
Go to Settings → Platform → Authentication, then Add SSO.
Select your identity provider from the grid — this sets the logo and pre-fills the name — and enter a display name.
The display name appears on your team's sign-in screen and can be changed later.
Click Continue. The connection is created in the Needs setup state.
Step 2 displays two values, each with a copy button:
| Autoheal calls it | Your IdP may call it |
|---|---|
| ACS URL (Reply URL) | Single sign-on URL, Reply URL, Assertion Consumer Service URL, ACS |
| Entity ID (Audience) | Audience URI, Identifier, SP Entity ID, Audience Restriction |
Both values are unique to the connection:
https://app.autoheal.ai/idps/384978418736854996/saml/acs
https://app.autoheal.ai/idps/384978418736854996/saml/metadata
Copy them from the wizard rather than typing them; they must match exactly in your IdP.
Create the SAML application in your IdP using these two values, release the user's email address (see Configure your IdP for per-provider steps), and assign your users to the application.
In step 2, supply your IdP's SAML metadata one of two ways:
- Metadata URL — paste the URL your IdP publishes.
- XML — paste the document or upload the
.xmlfile. Autoheal displays a parsed summary (Entity ID, sign-on URL, Name ID format, certificate present) for confirmation.
Leave Automatically create users on first login enabled unless you intend to pre-provision every user. See User provisioning.
Click Finish. The connection moves to Disabled — fully configured, with no effect on sign-in.
Select Test connection. A new tab runs a complete round trip against your IdP using your own account.
The result page reports what Autoheal received:
| Field | Meaning |
|---|---|
| The address Autoheal resolved | |
| Subject | Your IdP's internal user id |
| Display name | The name your IdP sent |
A test creates no session, provisions no user, and changes no enforcement. It can be run repeatedly.
If Email is blank, correct your attribute mapping before continuing. See What Autoheal expects in the assertion.
Select Enable and confirm.
Enabling the first connection in an organization requires SSO for all of its members: email one-time codes and Google sign-in stop working for them. Before enabling, confirm your IdP application is assigned to every user who needs access, and that Test connection returns an email address.
To remove the requirement, disable or delete every enabled connection. Email codes and Google sign-in resume immediately.
Connection states
| State | Meaning | Effect on sign-in |
|---|---|---|
| Needs setup | Created, no IdP metadata supplied | None. Cannot be enabled or tested. |
| Disabled | Fully configured and testable | None. |
| Enabled | Live | All members of the organization sign in through it. |
Expand any connection to review its protocol, binding, signed-request setting, provisioning setting, and SP details.
Break-glass access for admins
If your IdP is misconfigured or unavailable, administrators regain access at:
https://app.autoheal.ai/admin-auth?tenant=<your-organization>
<your-organization> is the first part of your Autoheal URL: for acme.autoheal.ai, it is acme.
The URL sends you through email-code sign-in and grants access only if your account holds the Admin or Owner role in that organization. The role check is enforced server-side. Every use is recorded in the audit trail.
Record this URL where your on-call administrators can reach it without signing in to Autoheal — a password manager or your incident runbook.
What your team sees
Once a connection is enabled:
- One enabled connection — users going to your Autoheal URL are sent directly to your IdP.
- Two or more — users select a connection by name and logo, then continue to it.
Sign-in must start from Autoheal. IdP-initiated sign-in — launching Autoheal from a tile in your IdP's dashboard — is not supported; point any such tile at your Autoheal URL.
What Autoheal expects in the assertion
Requirements
- A signed, unencrypted SAML 2.0 assertion. Assertion encryption is not supported.
- Audience matching the connection's Entity ID exactly.
- Destination matching the connection's ACS URL exactly.
- A valid time window (
NotBefore/NotOnOrAfter). Assertions from a badly-skewed clock are rejected. - The user's email address, in one of the forms below.
Email resolution
Autoheal looks for an attribute whose Name or FriendlyName matches one of the following, case-insensitively. The list is a priority order: if an assertion carries more than one, the highest wins, regardless of their order in the XML.
| Priority | Attribute name | Typically from |
|---|---|---|
| 1 | email | Okta, PingOne, most custom IdPs |
| 2 | mail | LDAP-backed providers |
| 3 | emailaddress | assorted |
| 4 | urn:oid:0.9.2342.19200300.100.1.3 | Shibboleth, SimpleSAMLphp |
| 5 | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | Entra ID, ADFS |
| 6 | http://schemas.xmlsoap.org/claims/emailaddress | older ADFS |
| 7 | user.email | assorted |
If no attribute matches, Autoheal falls back to the NameID, but only when its Format is urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress.
A NameID with format unspecified, persistent, or transient is not read as an email address, even when the value is one. Autoheal accepts a NameID as the email only where the IdP has explicitly typed it with the emailAddress format.
Example assertion
Trimmed to the elements Autoheal reads:
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ...>
<saml2:Subject>
<!-- Read as the email only with this exact Format. -->
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
dana@acme.com
</saml2:NameID>
</saml2:Subject>
<saml2:Conditions NotBefore="2026-08-12T09:00:00Z" NotOnOrAfter="2026-08-12T09:05:00Z">
<saml2:AudienceRestriction>
<!-- Must equal the connection's Entity ID exactly. -->
<saml2:Audience>https://app.autoheal.ai/idps/384978418736854996/saml/metadata</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AttributeStatement>
<!-- Highest priority of all resolution sources. -->
<saml2:Attribute Name="email">
<saml2:AttributeValue>dana@acme.com</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
Releasing both an email attribute and an emailAddress-format NameID is the most robust configuration.
Attributes Autoheal ignores
Group memberships, role attributes, department, employee id, and personal names are not read. Releasing them causes no harm, but no Autoheal behavior depends on them. Roles are assigned in Autoheal — see User provisioning.
Configure your IdP
The values below refer to the ACS URL and Entity ID shown in the wizard's step 2.
- Okta
- Microsoft Entra ID
- PingOne
Applications → Create App Integration → SAML 2.0.
On Configure SAML:
| Field | Value |
|---|---|
| Single sign-on URL | your ACS URL |
| Audience URI (SP Entity ID) | your Entity ID |
| Name ID format | EmailAddress |
| Application username | Email |
Add one attribute statement:
| Name | Name format | Value |
|---|---|---|
email | Unspecified | user.email |
Complete the wizard. On the application's Sign On tab, find the metadata URL — under SAML Signing Certificates → View IdP metadata, or the Metadata URL link — and paste it into Autoheal.
Under Assignments, assign the people or groups who need Autoheal.
Enterprise applications → New application → Create your own application → Integrate any other application you don't find in the gallery. Then Single sign-on → SAML.
Under Basic SAML Configuration:
| Field | Value |
|---|---|
| Identifier (Entity ID) | your Entity ID |
| Reply URL (ACS URL) | your ACS URL |
Under Attributes & Claims, set Unique User Identifier (Name ID) to source attribute user.mail, with name identifier format Email address.
Entra's default claim set includes http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress, which Autoheal accepts. If your tenant populates user.userprincipalname but not user.mail, add a claim named email sourced from the attribute holding the user's email address — otherwise Autoheal resolves a UPN rather than an email.
Copy App Federation Metadata Url from SAML Certificates into Autoheal, then assign Users and groups.
Applications → Add application → SAML Application.
Under Configuration:
| Field | Value |
|---|---|
| ACS URLs | your ACS URL |
| Entity ID | your Entity ID |
PingOne's default attribute mapping does not work with Autoheal. By default, a PingOne SAML application releases the email under an attribute named saml_subject and a NameID with no format. Autoheal reads neither as an email address, so every sign-in fails with error=sso_failed, and Test connection returns a blank Email.
Correct this under Attribute Mappings, either way:
- Recommended — add an attribute named exactly
email, mapped to the user's Email Address. Leave the existingsaml_subjectmapping in place. - Alternative — set the application's Subject NameID Format to
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress, withsaml_subjectmapped to Email Address.
Copy the metadata URL from the application's Configuration tab into Autoheal, then grant access to the appropriate groups.
For any other provider, the requirements in What Autoheal expects in the assertion are the full specification. Any SAML 2.0 IdP that can release an email attribute is supported.
Advanced options
The defaults suit most deployments. Under Show advanced options:
| Option | Default | When to change |
|---|---|---|
| Binding | HTTP-Redirect | Select HTTP-POST if your IdP requires it. HTTP-Artifact is also available. |
| Sign requests | Off | Enable if your IdP requires signed authentication requests. Autoheal's signing certificate is published in the connection's SP metadata. |
User provisioning
Automatically create users on first login — just-in-time (JIT) provisioning — is enabled by default. A user who authenticates through your IdP without an existing Autoheal account receives one.
JIT is governed by your organization's settings under Settings → Platform → Org Preferences → Just-In-Time User Provisioning:
| Setting | Effect |
|---|---|
| Enable JIT provisioning | When off, blocks all automatic account creation regardless of the connection's setting |
| Allowed email domains | Only these domains may be provisioned. Wildcards are supported: *.acme.com matches dana@acme.com and dana@eu.acme.com |
| Default role | Role assigned to provisioned users — Responder unless changed |
Both settings gate SSO sign-in for new users. A user whose IdP authentication succeeds is still refused if JIT is disabled or their email domain is not listed. Before enabling SSO, confirm every domain your workforce signs in with is on the allowlist.
To approve each account manually, disable the connection's toggle and invite users from Settings → Users first; SSO then signs in only accounts that already exist.
All provisioned users receive the same default role. Promote individuals from Settings → Users.
Removing a user in your IdP prevents further sign-in but does not delete their Autoheal account. Remove the account from Settings → Users.
Troubleshooting
Sign-in returns to the login page with error=sso_failed
Your IdP authenticated the user, but Autoheal could not read an email address from the assertion.
Run Test connection. If Email is blank, the cause is the attribute mapping — check the assertion requirements and your provider's tab above. PingOne's defaults fail this way, as do Entra tenants that populate userPrincipalName but not mail.
The same error covers a rejected assertion — invalid signature, wrong audience, expired time window. If Test connection does return an email, compare the Entity ID and ACS URL in your IdP against the connection's, character for character.
error=sso_org_mismatch
The assertion arrived from a connection that is not currently enabled for the organization it claims. Common causes: the connection was disabled or deleted while a sign-in was in flight, or an IdP application is pointed at another organization's ACS URL. Confirm the connection is Enabled and that your IdP application carries this connection's ACS URL and Entity ID.
A new user gets 'No access to this organization'
IdP authentication succeeded and provisioning was refused. Either JIT is disabled, or the user's email domain is not in Allowed email domains.
Check Settings → Platform → Org Preferences → Just-In-Time User Provisioning. Add the domain — *.acme.com covers subdomains — or invite the user from Settings → Users and have them retry.
Test connection reports the organization cannot be found
Run the test from your own Autoheal URL — https://<your-organization>.autoheal.ai — signed in as an Admin.
Members can no longer sign in with email codes
Expected behavior: an enabled connection requires SSO organization-wide. If unintended, an Admin can disable the connection under Settings → Platform → Authentication, and ordinary sign-in resumes immediately.
If no Admin can sign in, use the break-glass URL.
Sign-in worked previously and now fails
Two common causes: your IdP rotated its signing certificate — re-save the connection's metadata — or the IdP application's user assignments changed.
Users see a connection picker with only one provider in use
More than one connection is Enabled. Disable the connections not in use; a single enabled connection redirects without a picker.
Self-hosted deployments
Self-hosted Autoheal uses the same Settings → Platform → Authentication page, the same wizard, and the same assertion requirements. Two differences apply:
- The ACS URL and Entity ID are built from your deployment's domain, not
autoheal.ai. Copy them from the wizard. - Sign-in resolves your single organization automatically. One enabled connection redirects to your IdP; several produce the picker.
Break-glass access uses your deployment's sign-in domain:
https://<your-autoheal-sign-in-domain>/admin-auth?tenant=<your-organization>
Your Autoheal contact can confirm both values. Record them in your runbook before enabling SSO.
FAQ
Can we pilot SSO with a subset of users?
Not through enforcement — it applies to the whole organization. Use Test connection, which runs a complete round trip against your IdP with your own account and changes nothing for other users.
Can we keep both SSO and email codes available?
No. An enabled connection requires SSO for all members of the organization. Administrators retain access through the break-glass URL.
Do you support OIDC?
Not currently. Autoheal supports SAML 2.0.
How do roles work with SSO?
Independently. Your IdP asserts the user's identity; Autoheal determines their permissions. JIT-provisioned users receive your configured default role — Responder unless changed — and individuals can be promoted from Settings → Users. See Roles & Permissions.
What happens to API tokens when we enable SSO?
Nothing. Personal access tokens and service-account keys authenticate without a browser session and are unaffected by SSO enforcement. See API Credentials.
Can we migrate from one identity provider to another?
Yes. Add and configure the new connection, test it, then enable it — both connections are then enabled and users select one. Once the new connection is proven, disable the old one. Enforcement is continuous throughout.
Does enabling SSO sign everyone out?
No. Existing sessions continue until they expire. New sign-ins go through your IdP from the moment you enable.