Your values Fill in your own to see them in every example
The part after /o/ in your hub’s address.
That doesn’t look right yet. For example: a1B2c3D4e5F6
Scheme and host, no path: where your app runs.
That doesn’t look right yet. For example: https://app.example.com
Saved in this browser only, for every page of these docs. Nothing you type leaves this page.
Trustaige is a SAML 2.0 identity provider. A service provider that speaks SAML sends people to Trustaige, they sign in with their passkey, and Trustaige posts a signed assertion back saying who they are. Use SAML for a service that doesn’t offer OpenID Connect; for anything that does, set up an OpenID Connect app instead.
This page is for whoever connects the two sides: an administrator in the hub, and whoever configures single sign-on in the service provider. You need the permission to manage apps in your organization.
- Person to Service provider: opens the app
- Service provider to Trustaige: AuthnRequest to the SSO URL
- Person and Trustaige: passkey
- Trustaige to Service provider: signed Response, posted to the ACS URL
- Service provider to Person: signed in
Sign-in starts at the service provider: Trustaige answers an AuthnRequest,
and doesn’t send unsolicited responses. The app’s Launch URL in the hub
should therefore be an address at the service provider that starts its own
SAML sign-in.
The values a service provider needs
Every value is on the app’s page in the hub, in the Identity Provider
panel, ready to copy. Most of them carry your organization’s short ID, the part
after /o/ in your hub’s address.
| The service provider calls it | Hub label | Value |
|---|---|---|
| IdP entity ID, Issuer | IdP Entity ID (Issuer) | https://id.trustaige.com |
| Single sign-on URL | SSO URL | https://id.trustaige.com/o/<your-org-id>/saml/sso |
| Single logout URL | SLO URL | https://id.trustaige.com/o/<your-org-id>/saml/slo |
| Metadata URL | Metadata URL | https://id.trustaige.com/o/<your-org-id>/saml/metadata |
| Signing certificate, X.509 certificate | Signing Certificate | Shown in the hub; see The signing certificate |
The entity ID is the same for every organization. The SSO and SLO URLs are your organization’s own: Trustaige finds the app by the service provider’s entity ID within the organization the URL names, so a service provider pointed at another organization’s URL is refused.
Both URLs accept the HTTP-Redirect and HTTP-POST bindings.
The metadata
The Metadata URL serves a standard SAML 2.0 metadata document, with no
sign-in needed. Opening it in a browser downloads it as
trustaige-<your-org-id>-idp-metadata.xml, which is what the Download XML
button in the hub does. It contains:
- An
EntityDescriptorwithentityID="https://id.trustaige.com". - An
IDPSSODescriptorwith oneKeyDescriptor use="signing"for each certificate the service provider should trust, the one signing today first. - The NameID formats Trustaige supports:
unspecified,emailAddress,persistentandtransient. - A
SingleSignOnServiceand aSingleLogoutService, each for the HTTP-Redirect and HTTP-POST bindings, at your organization’s SSO and SLO URLs.
<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://id.trustaige.com">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIC…</ds:X509Certificate></ds:X509Data></ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://id.trustaige.com/o/<your-org-id>/saml/sso"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://id.trustaige.com/o/<your-org-id>/saml/sso"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://id.trustaige.com/o/<your-org-id>/saml/slo"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://id.trustaige.com/o/<your-org-id>/saml/slo"/>
</md:IDPSSODescriptor>
<md:Organization>…</md:Organization>
<md:ContactPerson contactType="technical">…</md:ContactPerson>
</md:EntityDescriptor>
While a new certificate is waiting to take over, there are two
KeyDescriptor elements; see Certificate rollover.
<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://id.trustaige.com">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIC…</ds:X509Certificate></ds:X509Data></ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://id.trustaige.com/o/<your-org-id>/saml/sso"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://id.trustaige.com/o/<your-org-id>/saml/sso"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://id.trustaige.com/o/<your-org-id>/saml/slo"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://id.trustaige.com/o/<your-org-id>/saml/slo"/>
</md:IDPSSODescriptor>
<md:Organization>…</md:Organization>
<md:ContactPerson contactType="technical">…</md:ContactPerson>
</md:EntityDescriptor>Create the app
You need two values from the service provider first: its entity ID (the
Issuer of the requests it sends) and its ACS URL (Assertion Consumer
Service: where it receives responses). Its own SAML settings page or its
metadata lists both.
- In the hub, go to Apps. Under In-house applications, click Create in-house app.
- Give it a name, and under Protocol choose SAML 2.0. Continue.
- Fill in SP Entity ID exactly as the service provider sends it.
- Fill in the ACS URL, for example
<your-app-url>/saml/acs. The hub marks it optional, but sign-in can’t complete without one: Trustaige has nowhere to send the response. - Choose a Name ID Format (see Who the assertion names). Email Address suits most services.
- Check the summary and click Create application.
- On the app’s page, copy the values from the Identity Provider panel into the service provider’s SAML settings, or give it the Metadata URL.
Choose who can use it. In the app’s Access section, assign the groups whose people may sign in. With none assigned, the section reads Open to everyone.
If the service provider signs its requests, open the app’s menu, choose Edit app, turn on Want AuthnRequests Signed, and paste its certificate under SP Signing Certificate (PEM or Base64 DER). Trustaige checks the signature of every request that carries one, so a service provider that signs needs its certificate here even if you don’t require signing.
What Trustaige sends
The response is posted to the ACS URL with the HTTP-POST binding.
| Issuer | https://id.trustaige.com on the response and the assertion |
| Signatures | The response and the assertion are both signed, always |
| Signature algorithm | RSA-SHA256 (http://www.w3.org/2001/04/xmldsig-more#rsa-sha256), SHA-256 digest, exclusive canonicalization |
| Encryption | Assertions aren’t encrypted |
| Audience | The service provider’s entity ID |
| Recipient, Destination | The ACS URL the response is posted to |
| Validity | NotBefore 2 minutes before issue (for clock skew), NotOnOrAfter 5 minutes after |
| Subject confirmation | bearer, with InResponseTo the request’s ID |
SessionIndex | Present; send it back in a LogoutRequest to end that session |
AuthnContextClassRef | urn:oasis:names:tc:SAML:2.0:ac:classes:FIDO, or urn:oasis:names:tc:SAML:2.0:ac:classes:HardwareToken when the person signed in with a security key proven to be hardware |
A requested authentication context isn’t enforced: Trustaige asserts the one
the person actually achieved. ForceAuthn="true" makes the person sign in
again, and IsPassive="true" gets a NoPassive status when they aren’t
signed in already.
Who the assertion names
The NameID follows the app’s Name ID Format. When the request’s
NameIDPolicy asks for a format Trustaige supports, that one wins.
| Format | Hub label | The NameID is |
|---|---|---|
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress | Email Address | The person’s email in your organization |
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified | Unspecified | The person’s email in your organization |
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent | Persistent | An opaque value, the same every time for this person and this service provider, and different at every other service provider |
urn:oasis:names:tc:SAML:2.0:nameid-format:transient | Transient | A new random value at every sign-in |
Choose Persistent when the service provider keys accounts on the NameID
and you don’t want an email change to orphan an account. NameQualifier is
https://id.trustaige.com and SPNameQualifier is the service provider’s
entity ID.
Attributes
Each attribute has the name format
urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified. An attribute with no
value is left out.
| Attribute | Value |
|---|---|
email | The person’s email in your organization |
uid | The person’s ID in your organization. It’s stable for as long as they’re a member, and different in every organization, so two organizations’ apps can’t use it to recognise the same person |
givenName | First name from their profile |
surname | Last name from their profile |
displayName | Their full name |
groups | The groups they belong to, directly or through a parent group, that are assigned to this app. Each is sent as the group’s slug, or its name when it has none |
roles | The roles they hold in this app (its own app roles, never their roles in the hub) |
deviceId | The device they signed in from, when Trustaige knows it |
collaborator.id, collaborator.name, collaborator.logo | For a person from a collaborating organization: that organization’s short ID, name and logo. Such a person gets no groups or roles |
When a profile has no first and last name, Trustaige splits the display name at its first space, because some service providers refuse a sign-in without both.
Rename attributes to what the service provider expects under Edit app →
Attribute Mappings: the left side is Trustaige’s name, the right side the name
sent. A new app starts with email, uid, givenName, surname and
displayName mapped to themselves.
The signing certificate
One certificate signs SAML for every organization on Trustaige. It is self-signed, so a service provider must trust the certificate itself rather than look for a certificate authority. The key is RSA 2048-bit, and each certificate is valid for a year.
The hub shows it under Signing Certificate in three forms; pick the one the service provider asks for:
| Tab | What you get |
|---|---|
| PEM | The certificate between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines. Download .pem saves it as certificate.pem |
| Base64 DER | The same certificate as one Base64 string with no header or footer. Download .der saves the binary certificate.der |
| SHA-256 | The certificate’s fingerprint, as colon-separated hex pairs. Use it to confirm a service provider holds the right one |
The Expires date shown with it is when the current certificate stops signing.
Certificate rollover
Trustaige replaces the signing certificate before it expires, and publishes the new one well ahead of the switch so every service provider can trust both.
- About 60 days before the current certificate expires, Trustaige creates the next one and adds it to the metadata, after the current one. It signs nothing yet.
- At the moment the current certificate expires, the new one starts signing every response, and moves to the top of the metadata.
- For a day after the switch, the retired certificate stays in the metadata, then it’s removed.
What the service provider has to do depends on how it got the certificate:
| The service provider… | What to do |
|---|---|
| Reads the Metadata URL | Nothing, as long as it refreshes the metadata before the switch |
| Had the certificate pasted in, and can hold several | Add the new certificate any time before the switch. Both are trusted until then, so adding it early is safe |
| Had the certificate pasted in, and holds only one | Replace it at the switch. Until then, responses are still signed with the current certificate |
In the hub, while a new certificate is waiting, the app’s Identity Provider panel shows A new signing certificate takes over on day, with the new certificate below it to copy. For apps that Trustaige configures in Microsoft Entra, Google Workspace or Cloudflare Access through an integration, Trustaige delivers the new certificate itself, retrying every hour, and the panel says when the provider already trusts it.
By email, your organization’s administrators hear about it about 60, 30 and 7 days before the switch, when at least one SAML app might need the certificate added by hand. The subject reads Action needed: update n SAML app(s) within n day(s), and the email gives the exact time of the switch in UTC, the new certificate’s SHA-256 fingerprint, and a Get the new certificate link.
Single logout
A service provider can end the person’s Trustaige session by sending a
LogoutRequest to the SLO URL, by HTTP-Redirect or HTTP-POST. Trustaige
ends the session the request’s SessionIndex names, and only when its NameID
names the same person. It replies with a signed LogoutResponse to the
service provider’s single logout address, which Trustaige knows only from the
service provider’s metadata; without one, the person lands on your
organization’s sign-in page instead.
Check it works
Open the service provider’s sign-in and choose single sign-on. You should land on your organization’s Trustaige sign-in, prove it’s you with your passkey, and come back signed in. Each sign-in appears in the hub’s Audit log.
Turn it off or remove it
- Pause sign-in: switch the app to Disabled at the top of its page.
The service provider then receives a
Requesterstatus with the messageApplication is disabled. - Remove it: in the app’s menu, choose Delete app. Remove Trustaige from the service provider’s settings too, so nobody is sent to an app that no longer exists.
Troubleshooting
“Access denied: you are not assigned to this application”
The app has groups assigned under Access, and the person isn’t in any of them. Add them to one of those groups, or assign a group they’re in.
“no application is configured for this service provider”
The request’s Issuer doesn’t match the app’s SP Entity ID in this
organization. Compare them character for character, including any trailing
slash, under Edit app → SAML Configuration → Entity ID. Also check the
service provider uses your organization’s SSO URL, with your short ID.
“failed to resolve ACS endpoint: requested ACS URL not registered”
The request asks for a response at an address the app doesn’t have. The ACS URL the service provider sends must match the app’s ACS URL exactly.
“failed to resolve ACS endpoint: no ACS endpoint configured for SP”
The app was created without an ACS URL, so Trustaige has nowhere to post the response.
“signature validation failed”
The service provider signed its request, and Trustaige couldn’t verify it. Turn on Want AuthnRequests Signed under Edit app and paste the service provider’s current certificate under SP Signing Certificate.
“unsupported NameID format”
The request’s NameIDPolicy asks for a format other than unspecified,
emailAddress, persistent or transient. Change the format the service
provider requests.
“This SAML endpoint requires an organization context.”
The organization short ID in the URL is wrong. Copy the URL again from the app’s Identity Provider panel.
The service provider rejects the signature after a certificate switch
It still trusts only the retired certificate. Give it the current one from Signing Certificate, or point it at the Metadata URL so the next switch takes care of itself.
The service provider says the response is expired or not yet valid
A response is valid from 2 minutes before it was issued until 5 minutes after. Check the clock on the service provider’s server.