Skip to content

Connect your identity provider to Truto so your team signs in to app.truto.one with the same login they use for everything else. Then, if you want, turn off every other way in.

Skip the reading — fast path for coding agents
CLI
truto sso-connections list --team-id <team_id>
Skill
View truto-cli skill on GitHub Cursor / Claude Code: /skill truto-cli
Info

Only team admins can manage SSO. The SSO tab under Settings appears only for admins, and every API call that changes a connection or a domain returns 403 for anyone else.

How it fits together

An SSO connection belongs to one team and uses one protocol: SAML 2.0 or OIDC. Most IdPs, including Okta, Microsoft Entra ID and Google Workspace, support at least one of them. A connection does four things:

  • It signs people in through your IdP.
  • It creates a Truto account the first time someone from a verified email domain signs in, using the connection's default role and environments.
  • It can enforce SSO, which turns off password, magic-link, Google, password-reset and passkey sign-in for people on its verified domains.
  • If it's the team's default connection, its default role and environments also apply to people your IdP provisions with SCIM.

You set it up in five steps: create a draft, register Truto with your IdP, paste the IdP's details back and activate, verify your domain, then test. Enforcement is optional and comes last.

1. Create a draft connection

Truto generates the URLs your IdP needs, and the IdP generates the values Truto needs. To get past that, create the connection first as an inactive draft.

  1. Open Settings → SSO (app.truto.one/settings/sso).
  2. Click Add connection.
  3. Pick a Protocol (OIDC or SAML 2.0) and click Continue.

Truto creates the connection as inactive and keeps the dialog open on the configure step. The connection's card shows Draft — not configured until you finish it. Under IdP configuration URLs, the card lists the values to register with your IdP:

Protocol Label Value
SAML SAML ACS URL https://api.truto.one/auth/saml/<connection_id>/acs
SAML SP Entity ID https://api.truto.one/auth/saml/<connection_id>/metadata
OIDC OIDC Callback URL https://api.truto.one/auth/oidc/<connection_id>/callback

The SAML SP Entity ID is also the URL of Truto's SP metadata. That URL serves the metadata XML only once the connection is active. While the connection is a draft, copy the ACS URL and SP Entity ID into your IdP by hand.

SAML ACS URL       https://api.truto.one/auth/saml/<connection_id>/acs
SP Entity ID       https://api.truto.one/auth/saml/<connection_id>/metadata
OIDC Callback URL  https://api.truto.one/auth/oidc/<connection_id>/callback

2. Register Truto with your identity provider

Create an application in your IdP and give it the values from step 1. The Truto values are the same whichever IdP you use. Only the IdP's screen names differ.

SAML

  • Use the SAML ACS URL as the IdP's Assertion Consumer Service (single sign-on, or reply) URL, and the SP Entity ID as its audience, or entity ID.
  • Send the user's email address as the NameID. Truto asks for the emailAddress NameID format. If the NameID isn't an email address, Truto reads the email from an attribute named email, mail, emailaddress, urn:oid:0.9.2342.19200300.100.1.3 or http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress.
  • To set the person's name, send a displayName, name or cn attribute, or givenName and surname. Without one, Truto uses the part of the email before the @.
  • Sign the response or the assertion. Truto rejects unsigned responses. Truto also accepts encrypted assertions, using the certificate in its SP metadata.

OIDC

  • Register the OIDC Callback URL as the application's redirect URI.
  • Truto uses the authorization code flow with PKCE (S256) and asks for the scopes openid email profile. It sends the client secret in the body of the token request.
  • The ID token must include an email claim. Truto doesn't use preferred_username.
  • The IdP must vouch for the address. It has to send email_verified: true in the ID token or from its userinfo endpoint, or Truto refuses the sign-in with The identity provider has not verified this email address.
Warning

Microsoft Entra ID doesn't send email_verified. If you connect Entra ID over OIDC, add the xms_edov optional claim to the ID token in your Entra app registration. Truto accepts xms_edov: true in its place. You can also connect Entra ID with SAML, which doesn't need the claim.

From your IdP, collect the values you'll paste back in step 3:

SAML:  IdP metadata XML file
       (or: IdP SSO URL, IdP entity ID, IdP X.509 signing certificate in PEM format)
OIDC:  Client ID, client secret, issuer URL (or OpenID discovery URL)

3. Paste the IdP details and activate

Go back to the dialog. If you closed it, open the connection's menu on its card and choose Edit.

SAML

  • Use IdP metadata XML is on by default. Click Upload IdP metadata XML and pick the file from your IdP. Truto reads the IdP's SSO URL, entity ID and signing certificate from it, then throws the XML away.
  • To enter the values yourself, turn Use IdP metadata XML off and fill in IdP SSO URL, IdP Entity ID and IdP X.509 Certificate (PEM).
  • Under Advanced:
    • Sign AuthnRequests signs the sign-in requests Truto sends with Truto's SP key. Turn it on if your IdP requires signed requests. The IdP gets Truto's certificate from the SP metadata URL.
    • Allow IdP-initiated login accepts sign-ins that start from your IdP's dashboard or app launcher. It's off by default, so Truto accepts only sign-ins it started itself. Turn it on only if your IdP or your team needs it.

OIDC

  • Fill in Client ID, Client Secret and Issuer / Discovery URL. Truto finds the IdP's endpoints from <issuer>/.well-known/openid-configuration. The client secret is write-only: Truto encrypts it and never returns it. Later edits show Client secret is configured, with a Change link.

Both protocols

  • Under First-login provisioning, choose a Default role. For Member, tick at least one of the Default environments. Admins get every environment automatically. See Default access for new people.
  • Turn on Active. This switch stays disabled until the required IdP fields are filled in.
  • Leave Enforce SSO off for now. Turn it on after you've tested sign-in (step 6).
  • Set as default connection marks the connection SCIM uses. Truto turns it on for a team's first connection.

Click Save.

Truto refuses to activate a connection that's missing any of these fields:

Protocol Required to activate
SAML idp_sso_url, idp_entity_id and idp_x509_cert. Uploading IdP metadata XML fills all three.
OIDC issuer, client_id and a client secret

When a field is missing, the API returns 400 with a message like this one:

Cannot activate this SAML SSO connection — missing idp_x509_cert. Save it as inactive until your identity provider is configured, then activate it.

4. Add and verify your email domain

On the connection's card, under Email domains, type your domain (for example example.com) and click Add domain. The domain shows Pending verification, and the card shows the TXT record to publish:

truto-domain-verification=<verification_token>

Add that TXT record to the domain itself (example.com, not a subdomain), then click Verify. When the record is found, the domain changes to Verified. If it isn't found yet, the toast says Domain not verified yet and explains what was missing. DNS changes can take a while to propagate, so wait a few minutes and click Verify again. To check the record yourself:

dig +short TXT example.com

Only Truto staff can mark a domain verified without the DNS check.

Why verification matters

A connection with no verified domain can only be reached through its direct login link. Verifying a domain changes four things:

  • Sign in with SSO works. On the Truto login page, Sign in with SSO finds a connection from the domain of the work email the person types. Only verified domains on active connections match.
  • New people can join on first sign-in. Someone with no Truto account who signs in through the connection gets one, on this team, with the default role and environments. Truto does this only for addresses on a verified domain. Anyone else is refused with Email domain is not verified for this SSO connection.
  • Existing users can sign in with SSO. People who already have a Truto account, for example because you invited them and they set a password, can use SSO only if:
    • their email's domain is verified on that connection,
    • they're already a member of the connection's team (otherwise: User is not a member of this organization),
    • and their account is active.
  • Enforcement reaches them. Enforcing SSO applies only to people on the connection's verified domains.

5. Test sign-in

On the connection's card, open the menu and choose Test login. Truto sends you through your IdP and back to Settings → SSO. For an existing admin, that works once your domain is verified (step 4).

Your team can now sign in two ways:

  • On the Truto login page, enter a work email and click Sign in with SSO.
  • Open the connection's direct login link:
https://api.truto.one/auth/saml/<connection_id>/login
https://api.truto.one/auth/oidc/<connection_id>/login

If a sign-in fails, Truto shows the reason on its error page, for example SAML assertion has expired (NotOnOrAfter) or The identity provider has not verified this email address.

6. Enforce SSO

Once sign-in works, open the connection with Edit, turn on Enforce SSO and click Save. The card shows an SSO enforced badge.

Enforcement applies to everyone on one of the connection's verified domains who is a member of the team (or, for an address with no account yet, everyone on those domains). For them, Truto turns off every other way to sign in:

Sign-in method What they see
Password Password login is disabled for this organization. Please use SSO.
Magic link Password and magic-link login are disabled for this organization. Please use SSO.
Sign in with Google Social login is disabled for this organization. Please use SSO.
Password reset Password login is disabled for this organization. Please use SSO.
Passkey sign-in Passkey sign-in is disabled for this organization. Please use SSO.
Registering a new passkey Passkeys are disabled for this organization. Please use SSO.

A few details decide who's covered:

  • Only active connections enforce. Turning Active off on a connection also stops its enforcement.
  • Other domains are not affected. Members whose email domain isn't verified on an active connection of the team keep their other sign-in methods. That includes guests from other companies and members whose domain you removed.
  • It follows the person, not the team. A Truto account belongs to one person across all their teams. If any of their teams enforces SSO for their domain, they sign in with SSO everywhere.
Warning

If your IdP breaks or the connection is misconfigured, everyone on the enforced domains is locked out until enforcement is turned off. Before you enforce, make sure an admin can still sign in another way, for example an admin whose email is on a domain that isn't verified for the connection.

Default access for new people

The First-login provisioning settings decide what a new person gets the first time they sign in through the connection:

  • Default role: Member. They get access to the Default environments you ticked. At least one is required. Without one, first sign-in fails with Cannot JIT-provision user without default environments.
  • Default role: Admin. They get access to every environment of the team.

If the person belongs to SCIM groups with group mappings, the mappings decide their role and environments instead.

The team's default connection is the active connection marked Set as default connection. If none is marked, it's the oldest active connection. SCIM provisioning uses the default connection's role and environments. A team has one default at a time: marking a connection as default clears the flag on the others. Choose Set as default from a card's menu to switch.

Deleting a connection also deletes its domains. If the connection was enforced, make sure the people on those domains have another way to sign in.

API and CLI

The same settings are available through the Truto API under /sso-connection:

Method and path What it does
GET /sso-connection?team_id=<team_id> List connections. Filters: protocol, is_active, enforced, is_default.
POST /sso-connection Create a connection. Requires team_id and protocol. is_active defaults to true, so send "is_active": false to create a draft.
GET /sso-connection/<id> Get one connection. The client secret and SP keys are never returned.
PATCH /sso-connection/<id> Update a connection. config is merged into the stored config. config.idp_metadata_xml is parsed into the idp_* fields.
DELETE /sso-connection/<id> Delete a connection and its domains.
GET /sso-connection/<id>/domains List the connection's domains with verified and verification_token.
POST /sso-connection/<id>/domains Add a domain ({"domain": "example.com"}). The response includes verification_record, the exact TXT value to publish.
POST /sso-connection/<id>/domains/<domain>/verify Run the DNS check. Returns {"domain", "verified"}, plus detail when the record wasn't found.
DELETE /sso-connection/<id>/domains/<domain> Remove a domain.

The connection object carries protocol, is_active, enforced, is_default, default_role, default_environment_ids and a config holding idp_entity_id, idp_sso_url, idp_x509_cert, sign_authn_requests and allow_idp_initiated (SAML) or issuer, client_id and discovery_url (OIDC).

Warning

Every write needs a team admin. API tokens carry no team role, so with an API token the POST, PATCH and DELETE calls above (verifying a domain included) return 403 Only team admins can manage SSO connections. Make changes in the console. With an API token, you can read connections and domains.

The CLI signs in with an API token, so the read commands work:

truto sso-connections list --team-id <team_id>
truto sso-connections get <connection_id>
truto sso-connections domains <connection_id>
# List the team's SSO connections
curl "https://api.truto.one/sso-connection?team_id=<team_id>" \
  -H "Authorization: Bearer <API token>"
 
# List a connection's domains and their verification state
curl "https://api.truto.one/sso-connection/<connection_id>/domains" \
  -H "Authorization: Bearer <API token>"

The CLI also has create, update, delete, add-domain, remove-domain and verify-domain. Like the API calls, they need a team admin, so they return 403 with an API-token profile.

Next

To create and remove team members from your IdP, and to map IdP groups to roles and environments, set up SCIM provisioning. To add a second factor for people who still sign in with a password, see Two-factor authentication and passkeys.