Skip to Content
Admin GuidesSAML Authentication

SAML Authentication

Ascender Ledger Pro can delegate sign-in to your organization's identity provider (IdP) using SAML 2.0. Ledger Pro acts as the Service Provider (SP): it never stores SSO passwords, and it provisions accounts automatically the first time a user signs in.

Bring your own identity provider

Ledger Pro works with any standards-compliant SAML 2.0 identity provider, including Auth0, Okta, Keycloak, Microsoft Entra ID, and AD FS. CIQ does not publish a separate procedure for each provider. The values Ledger Pro needs are the same everywhere, and the Auth0 example below shows where a typical provider exposes them.

Before you begin

You need all of the following:

  • An application registered for Ledger Pro in your identity provider. Most providers call this an application, a client, or a relying party.
  • The IdP metadata for that application: its issuer (entity ID), single sign-on URL, and signing certificate.
  • Administrator access to Ledger Pro, so you can reach Settings then Authentication.
  • Ledger Pro served over HTTPS. Sign-in works without TLS, but one validation step is skipped. See Serve Ledger Pro over HTTPS.

How SAML sign-in works

  1. The user selects Log in to your Company on the Ledger Pro login page.
  2. Ledger Pro builds an authentication request and sends it to your IdP's single sign-on URL using the configured binding method.
  3. The user authenticates at the IdP.
  4. The IdP posts a signed SAML response back to Ledger Pro's assertion consumer service (ACS) endpoint.
  5. Ledger Pro validates the response, maps the returned attributes to account fields, creates or updates the local account, reconciles team membership, and starts the session.

Sign-in started from the IdP's own dashboard (IdP-initiated sign-in) is also supported. Every validation still applies, except the correlation between the response and a request Ledger Pro sent.

SAML endpoints

These endpoints are public and do not require an existing session, because your IdP posts to them across sites.

PurposeMethodPath
Start sign-in from Ledger ProGET/login_saml/
Assertion consumer servicePOST/acs

Configure SAML in Ledger Pro

Open Settings, select Authentication, then select the SAML tab. Turn on Enable SAML and complete both columns, then select Save.

The SAML tab of the Authentication settings page

Enabling SAML adds a Log in to your Company button to the login page. Local and LDAP sign-in continue to work, so you do not lose access to the local admin account while you are setting SAML up.

Service Provider information

This column describes Ledger Pro itself. You register these values with your identity provider.

FieldRequiredDescription
Sign RequestsNoSigns outgoing authentication and logout requests with the SP private key, using RSA-SHA256. Requires the certificate and private key below.
Entity IDYesLedger Pro's unique identifier, typically its base URL, for example https://ledger.example.com/. This value must match the audience your IdP places in the assertion.
Assertion Consumer Service URLYesThe public URL your IdP posts the SAML response to. It must end in /acs, for example https://ledger.example.com/acs.
Public CertificateOnly when signingThe SP public X.509 certificate, uploaded as a PEM file.
Private KeyOnly when signingThe matching private key, uploaded as a PEM file and stored encrypted.

The ACS URL is also the value Ledger Pro sends as the AssertionConsumerServiceURL in its authentication request, so your identity provider must accept it as a valid reply URL for the application.

Certificate and key uploads persist

The certificate and private key fields only store a value when you upload a file, and they show [ saved ] once one is stored. Re-saving the form without re-uploading keeps the existing certificate and key.

Identity Provider information

This column describes your IdP. Every value comes from the IdP metadata for the application you registered.

FieldRequiredDescription
Entity IDYesThe IdP's issuer. Ledger Pro compares this against the issuer in every response.
Single SignOn URLYesThe IdP endpoint Ledger Pro sends authentication requests to.
Logout Service URLNoThe IdP's single logout endpoint. Not currently used, see Logging out. Leave blank.
Public CertificateYesThe IdP signing certificate, pasted as a PEM block or as bare base64. Used to verify the signature on the response.
The IdP Entity ID is an issuer, not a client ID

Entity ID under Identity Provider information must be the issuer your IdP advertises, for example urn:your-tenant.us.auth0.com. It is not an OAuth or OIDC client ID or application ID. Some providers present a client ID more prominently than the issuer, and using it here is the most common cause of a failed SAML sign-in. See Troubleshooting.

Binding method

Binding Method controls how Ledger Pro sends its authentication and logout requests to the IdP:

MethodBehavior
Redirect BindingThe request travels in the URL of a browser redirect. This is the default.
Post BindingThe request travels in the body of an auto-submitting HTML form.

Both are supported, and most identity providers accept either. Your IdP always returns its response to the ACS endpoint by HTTP POST, whichever binding you choose for the outgoing request.

Sign requests

Signing outgoing requests is optional. It lets the IdP verify that a request genuinely came from your Ledger Pro instance. If your IdP requires signed requests, turn on Sign Requests and upload an X.509 certificate and private key.

A self-signed pair is acceptable for most providers. To generate one:

openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 365 -out certificate.pem

If your identity provider requires a certificate signed by a known certificate authority, have the certificate signed before uploading it.

Serve Ledger Pro over HTTPS

When Ledger Pro starts a sign-in, it stores the request ID in a short-lived cookie marked Secure, then checks that the IdP's response corresponds to that request. On a deployment that browsers reach over plain HTTP, the cookie is dropped and Ledger Pro treats the response as IdP-initiated, skipping only that correlation check. All signature, issuer, audience, destination, and timestamp validation still applies.

Serve Ledger Pro over HTTPS in production so this check is active. A TLS-terminating proxy satisfies this as long as the browser reaches Ledger Pro over https://.

How responses are validated

Ledger Pro rejects any SAML response that fails any of these checks:

CheckRequirement
SignatureThe response, or every assertion in it, must be signed and verify against the configured IdP public certificate. Unsigned messages are rejected.
IssuerThe response issuer must equal the IdP Entity ID.
AudienceThe assertion audience must equal the SP Entity ID. This is what stops a token minted for another application from being replayed into Ledger Pro.
DestinationThe destination or recipient must match the Assertion Consumer Service URL.
TimestampsThe issue instant, the assertion validity window, and the subject confirmation expiry must all be current, allowing for small clock skew.
Request correlationFor sign-ins started from Ledger Pro, the response must correspond to the request Ledger Pro sent. Skipped for IdP-initiated sign-in.
StatusThe SAML status must be success.

Attribute mapping

Your IdP decides which attributes it sends in the assertion. Configuring that mapping in the IdP is the step most often missed, because Ledger Pro can only populate the fields your IdP actually sends.

Ledger Pro normalizes each incoming attribute name by taking the last path segment of the attribute Name, falling back to its FriendlyName, and lower-casing it. A claim sent as http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress therefore arrives as emailaddress and maps to the email field. You do not need to strip the schema prefix yourself.

Ledger Pro recognizes these attribute names:

Attribute name sent by the IdPMaps to
email, mail, emailaddressEmail
username, nickname, userprincipalname, samaccountnameUsername
givenname, firstnameGiven name
surname, lastnameSurname
name, displayname, commonname, preferrednameFull name
nameidentifierName ID
privatepersonalidentifierID
clientidSession ID
roleProfile
group, groupsGroups, multi-valued

Notes on this table:

  • Any one of the listed aliases works. Send mail or email or emailaddress, whichever your IdP produces natively.
  • Both group and groups are accepted. The SAML 2.0 specification uses the singular form, but many identity providers send the plural, so Ledger Pro handles either.
  • Ledger Pro resolves the account by username first, or by name ID when no username attribute is present, then by email. When no account matches, it creates one with the type saml.
  • role populates a profile field that Ledger Pro stores on the account but does not currently act on. Identity providers that send a role or group list by default, Keycloak among them, will populate it. There is no need to suppress the attribute at the identity provider.
  • Display name and email are refreshed from the IdP on every sign-in. The display name is derived from given name plus surname, then a full-name attribute, then username, then email.
Minimum viable mapping

Sending a username attribute and an email attribute is enough to sign in. Add a given name and surname for a readable display name, and add groups if you want automatic team placement.

Mapping groups to teams

Team membership is driven entirely by the group or groups attribute.

  1. Configure your IdP to send group or role membership in a group or groups attribute.
  2. In Ledger Pro, open Admin then Teams, and set the SAML Group Name field on each team to the matching group name from your IdP.

On every SAML sign-in, for each team that has a SAML Group Name configured, Ledger Pro adds the user when the assertion's group values contain that name and removes the user when they do not. Teams with no SAML Group Name are left untouched, so locally managed teams are unaffected.

Because your IdP is authoritative for group membership, removing a user from a group in the IdP removes them from the corresponding Ledger Pro team on their next sign-in.

SAML users and permissions

SAML users do not need an email invitation. They are registered automatically on first sign-in with minimal permissions, and pick up further permissions from the teams their groups map to. See Users and Teams.

Logging out

When a SAML user logs out of Ledger Pro, the local Ledger Pro session is cleared and the user is returned to the login page.

Single Logout is not currently supported

Ledger Pro does not currently implement SAML Single Logout. The Logout Service URL field is present on the settings page, but Ledger Pro exposes no SLO return endpoint, so logging out of Ledger Pro does not end the session at your identity provider. Leave the field blank. Single Logout is planned for a future release.

The practical effect is that a user who logs out of Ledger Pro and then selects Log in to your Company again is signed straight back in, because their IdP session is still active. To fully sign out, the user must also log out at the identity provider, or wait for the IdP session to expire.

This is normal for many single sign-on deployments: identity providers commonly end sessions on their own schedule or after a period of inactivity rather than on demand.

Testing your configuration

Save the SAML settings first, then use the Test button on the SAML settings page. It validates the saved configuration: required fields are present, the certificates and key parse correctly, and the service provider can be assembled.

The test does not perform a browser round trip to your IdP. Confirm end-to-end sign-on by signing out and selecting Log in to your Company on the login page, using an account that is a member of at least one mapped group.

Troubleshooting

Set DEBUG=true to log the full assertion and each validation step. See Configuration for logging options.

SymptomCause and fix
invalid xml: no rootThe SAML response field was empty or was not valid XML. Confirm your IdP posts to the correct Assertion Consumer Service URL.
response Issuer does not match the IDP metadataThe IdP Entity ID does not equal the issuer in the response. Set it to the issuer your IdP advertises, not a client or application ID.
Your IdP rejects the request before showing a login form, for example a client or application not found errorThe identity provider does not recognize the SP Entity ID that Ledger Pro sent as its issuer. The registered value at the IdP must match it character for character, trailing slash included. Compare them using the technique below.
assertion Conditions AudienceRestriction does not contain ...The SP Entity ID does not match the audience your IdP sent. Make the two identical, and watch for a trailing slash on one but not the other.
Destination or recipient mismatchThe Assertion Consumer Service URL must match the URL your IdP posts to exactly, including scheme, host, port, and path.
Signature errorsThe IdP Public Certificate is missing or wrong, or the message is unsigned. Confirm your IdP signs the response or the assertion, and that the certificate you pasted matches the IdP's current signing key.
Request correlation skipped, treated as IdP-initiatedExpected on deployments not served over HTTPS, and on genuine IdP-initiated sign-in. See Serve Ledger Pro over HTTPS.
Sign-in succeeds but the user has no teamsYour IdP is not sending a group or groups attribute, or the SAML Group Name on the team does not match the value sent. Enable debug logging and check the attributes in the assertion.
Sign-in succeeds but the display name is blank or oddYour IdP is not sending name attributes. Map a given name and surname, or a full-name attribute, in the IdP.

If sign-in still fails after working through this table, contact CIQ Support with the debug log for a failed attempt.

Finding the exact values Ledger Pro sends

Mismatches between Ledger Pro and your identity provider are usually a character-level difference in the SP Entity ID, and the fastest way to settle one is to read the authentication request Ledger Pro actually builds.

Request the SAML sign-in endpoint and decode the SAMLRequest value out of the form it returns:

curl -s https://ledger.example.com/login_saml/ \ | grep -o 'name="SAMLRequest" value="[^"]*"' \ | sed 's/.*value="//; s/"$//' \ | base64 -d

The decoded XML shows the exact Issuer (your SP Entity ID), AssertionConsumerServiceURL, Destination, and ProtocolBinding that Ledger Pro is sending. Register those values at your identity provider verbatim.

Identity provider example: Auth0

Auth0 is a convenient provider to validate a configuration against, and a developer account is free. The same values exist in every SAML 2.0 provider under different names.

In Auth0, create an application, then open its Addons tab and enable SAML2 Web App. The Usage tab of that addon exposes the IdP metadata, the identity provider login URL, and the signing certificate.

Map the values as follows:

Ledger Pro settingAuth0 value
IdP Entity IDThe issuer, for example urn:your-tenant.us.auth0.com. Not the Auth0 client ID.
IdP Single SignOn URLhttps://your-tenant.us.auth0.com/samlp/<client-id>
IdP Logout Service URLThe SAML logout endpoint for the application.
IdP Public CertificateThe signing certificate from the application's SAML metadata.
SP Entity IDRegister this value as the audience in the SAML2 addon settings.
SP Assertion Consumer Service URLhttps://ledger.example.com/acs, also set as the application callback URL.

Two Auth0 specifics are worth calling out:

  • Auth0 does not send a full name attribute by default, and it identifies users by nickname rather than username. Both map correctly in Ledger Pro, but declare the attributes you want in the Settings tab of the SAML2 addon.
  • Groups are not available in a base Auth0 tenant. Add the Auth0 authorization extension, create roles or groups there, and have the addon send them as a groups attribute.