ArticlesAscender

Configuring Keycloak as a SAML 2.0 identity provider for Ascender Ledger Pro

ascenderhow-toconfigurationsecurity

Arian Cabrera
Sr. Customer Support Engineer

Sep 16, 2026

Introduction

Ascender Ledger Pro supports SAML 2.0 single sign-on, acting as the Service Provider and delegating authentication to your identity provider. The product documentation describes the SAML settings in provider-neutral terms, because Ledger Pro works with any standards-compliant SAML 2.0 identity provider.

This article covers Keycloak specifically: which Keycloak value belongs in which Ledger Pro field, the attribute mappers Keycloak needs before Ledger Pro can populate an account, and the two errors that come up most often.

Keycloak is a fully independent identity provider. It does not require a third-party provider behind it, although it can also broker to one. Either way Ledger Pro only ever communicates with Keycloak, so the configuration below applies in both cases.

Applies to Ascender Ledger Pro 1.1.0, verified against Keycloak 26.

Problem

Keycloak names several of the values Ledger Pro asks for differently, and a stock Keycloak client does not send the user attributes Ledger Pro needs. As a result a first attempt at SAML sign-on typically fails in one of three ways: Keycloak rejects the request before showing a login form, Keycloak refuses to authenticate at all, or sign-in succeeds but the user arrives with no display name and no team membership.

Symptoms

Keycloak displays an error page before any login form appears:

We are sorry...
Invalid Request

Or Keycloak refuses to present a login form:

We are sorry...
HTTPS required

Or sign-in completes, but the new user in Ledger Pro has a blank or odd display name and belongs to no teams.

Resolution

Create a realm, a group, and a user

These examples use kcadm.sh, which ships with Keycloak. The same steps are available in the administration console.

kcadm.sh config credentials --server https://keycloak.example.com \
  --realm master --user admin --password '<admin-password>'

kcadm.sh create realms -s realm=ciq -s enabled=true
kcadm.sh create groups -r ciq -s name=ledger-admins
kcadm.sh create users -r ciq -s username=user -s enabled=true \
  -s email=user@example.com -s firstName=Example -s lastName=User \
  -s emailVerified=true
kcadm.sh set-password -r ciq --username user --new-password '<user-password>'

Add the user to the group by updating users/<user-id>/groups/<group-id> in the same realm.

Create the SAML client

Create a client whose Client ID is exactly the Entity ID that Ledger Pro sends. Keycloak matches the incoming request to a client by that value, and a difference of a single character causes the Invalid Request error above.

{
  "clientId": "https://ledger.example.com/",
  "name": "Ascender Ledger Pro",
  "protocol": "saml",
  "enabled": true,
  "frontchannelLogout": true,
  "redirectUris": ["https://ledger.example.com/*"],
  "attributes": {
    "saml.server.signature": "true",
    "saml.assertion.signature": "true",
    "saml.signature.algorithm": "RSA_SHA256",
    "saml.client.signature": "false",
    "saml_name_id_format": "username",
    "saml_force_name_id_format": "true",
    "saml.force.post.binding": "true",
    "saml_assertion_consumer_url_post": "https://ledger.example.com/acs",
    "saml_assertion_consumer_url_redirect": "https://ledger.example.com/acs",
    "saml_single_logout_service_url_post": "https://ledger.example.com/slo",
    "saml_single_logout_service_url_redirect": "https://ledger.example.com/slo"
  }
}

Ledger Pro rejects unsigned messages, so leave both Sign Documents (saml.server.signature) and Sign Assertions (saml.assertion.signature) enabled.

ℹ️ NOTE The single logout URLs are included above so the client is complete, but Ledger Pro does not implement SAML Single Logout in this release. Logging out of Ledger Pro clears the local session only, and the Keycloak session stays active until it expires. Leave the Logout Service URL blank in Ledger Pro. Single Logout is planned for a future release.

Set Client Signature Required (saml.client.signature) to true only when you also enable Sign Requests in Ledger Pro and upload a certificate and private key there. Otherwise leave it false, or Keycloak will reject Ledger Pro's unsigned authentication requests.

Add the attribute mappers

Ledger Pro normalizes each incoming attribute by taking the last path segment of its name and lower-casing it. Naming the mappers as shown below lands them on the fields Ledger Pro expects, with no schema prefix required.

Mapper name Mapper type Source Attribute name to set
username User Property username username
email User Property email email
givenname User Property firstName givenname
surname User Property lastName surname
groups Group list group membership groups

Set the attribute name format to Basic on all five. On the group mapper, set Single Group Attribute to off and Full group path to off, so each group arrives as its own value and without a leading path.

Without these mappers Keycloak authenticates the user but sends almost nothing about them, which produces the blank display name and empty team list described above.

Collect the identity provider values

Every value Ledger Pro needs is published in the realm descriptor:

https://keycloak.example.com/realms/ciq/protocol/saml/descriptor
Ledger Pro field Keycloak value
Identity Provider Entity ID https://keycloak.example.com/realms/ciq
Single SignOn URL https://keycloak.example.com/realms/ciq/protocol/saml
Logout Service URL Same as the Single SignOn URL
Identity Provider Public Certificate The X509Certificate value from the descriptor

⚠️ WARNING The Identity Provider Entity ID is the realm issuer URL, not a client ID. Pasting a client ID here is a common mistake for anyone used to OIDC, and it fails with a message about the response issuer not matching the identity provider metadata.

To pull the signing certificate out of the descriptor as a PEM block:

curl -s https://keycloak.example.com/realms/ciq/protocol/saml/descriptor \
  | grep -o '<ds:X509Certificate>[^<]*' \
  | sed 's/.*>//' \
  | fold -w 64 \
  | sed -e '1i -----BEGIN CERTIFICATE-----' -e '$a -----END CERTIFICATE-----'

Configure Ledger Pro

In Ledger Pro, open Settings, select Authentication, then the SAML tab. Enable SAML and enter the values below, then save.

Field Value
Binding Method Post Binding
Service Provider Entity ID https://ledger.example.com/
Assertion Consumer Service URL https://ledger.example.com/acs
Sign Requests Off, unless you enabled Client Signature Required above
Identity Provider Entity ID https://keycloak.example.com/realms/ciq
Single SignOn URL https://keycloak.example.com/realms/ciq/protocol/saml
Identity Provider Public Certificate The certificate from the previous step

Local and LDAP sign-in continue to work while SAML is enabled, so you keep access to the local administrator account while configuring this.

Map the Keycloak group to a Ledger Pro team

Open Admin, then Teams, and set SAML Group Name on a team to the Keycloak group name, for example ledger-admins. Grant the team whatever permissions its members should inherit.

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

Because Keycloak is authoritative, removing a user from the group in Keycloak also removes their Ledger Pro team membership, and the permissions that team granted, at their next sign-in.

Test the configuration

Save the settings first, then use the Test button on the SAML settings page. It validates the stored configuration: required fields are present, the certificate parses, and the service provider can be assembled. It does not perform a browser round trip to Keycloak.

To confirm end to end, sign out of Ledger Pro, start a SAML sign-in from the login page, and authenticate as a Keycloak user who belongs to the mapped group. A successful sign-in creates the Ledger Pro account automatically, with no invitation required, and places the user in the mapped team.

Notes

The Entity ID is sent verbatim, including any trailing slash

Ledger Pro sends its Service Provider Entity ID exactly as configured. https://ledger.example.com/ and https://ledger.example.com are two different identifiers, and Keycloak treats them as such. If Keycloak returns Invalid Request before showing a login form, the Keycloak server log records the reason:

type="LOGIN_ERROR" error="client_not_found" reason="Cannot_match_source_hash"

To see exactly what Ledger Pro sends, request its SAML sign-in endpoint and decode the request:

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

The decoded XML contains the Issuer, which is the Service Provider Entity ID, along with the AssertionConsumerServiceURL, Destination, and ProtocolBinding. Make the Keycloak Client ID identical to that Issuer.

Keycloak refuses to authenticate over plain HTTP

Keycloak realms default to requiring TLS for any client that is not on a private address, which produces the HTTPS required message. The correct fix is to serve Keycloak over TLS.

⚠️ WARNING Only relax this in a disposable proof-of-concept environment, never on a production identity provider.

kcadm.sh update realms/ciq -s sslRequired=NONE

Both singular and plural group attributes are accepted

Ledger Pro accepts either group or groups as the attribute name. The SAML 2.0 specification uses the singular form, while many identity providers, Keycloak included, send the plural. Either works, so there is no need to rename the mapper.

Signature algorithm

Ledger Pro signs its own outgoing requests, when request signing is enabled, with RSA-SHA256, and accepts RSA-SHA256 signed responses from Keycloak. The RSA_SHA256 setting shown in the client configuration above is correct and does not need changing.

Ascender Ledger Pro SAML authentication guide

Ascender Ledger Pro administration guide