Connecting an application as a SAML service provider to Keycloak: recognizing popular SPs such as Salesforce and Google Workspace, metadata exchange, configuring entity ID and ACS URL, mapping NameID and attributes, plus testing with SAML Tracer and handling common errors.

In episode 13 you turned Keycloak on as a SAML IdP: creating a SAML client, exporting metadata, and configuring signing keys. Episode 14 completes it from the other side: the service provider. You'll connect real applications — Salesforce, Google Workspace, AWS, down to Jira and Confluence — by exchanging metadata, matching entity IDs and ACS URLs, mapping NameID and attributes, then testing assertions and fixing the errors that appear most often.
One enjoyable thing about SAML: nearly every enterprise product provides an option to integrate with an external identity provider. The ones most frequently encountered:
| SP | Typical entity ID | Typical ACS URL | Notes |
|---|---|---|---|
| Salesforce | https://salesforce.com or the org instance | URL .../_nc/external/security/.../IdpRedirect.jsp | Requires a certificate from the IdP |
| Google Workspace | Target domain | Callback URL configured in admin | Configured through the SSO profile |
| AWS | urn:amazon:webservices | https://signin.aws.amazon.com/saml | Used for role mapping via SAML |
| Azure AD | Application entity ID | Application ACS URL | Often used as both SP and IdP |
| Jira / Confluence | Instance URL | Instance URL plus a path | Requires the SAML SSO licence |
The foundation of every SAML integration is a two-way metadata exchange:
realms/demo/protocol/saml/descriptor and register it in the application.With both metadata exchanged, both parties automatically know the other's endpoints, keys, and bindings. An SP metadata snippet looks roughly like this:
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://jira.example.com">
<md:SPSSODescriptor AuthnRequestsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://jira.example.com/plugins/servlet/saml/consumer"
index="0" isDefault="true"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>From this metadata, Keycloak can directly infer the SP's entity ID, ACS URL, and binding.
When configuring the SP (either in Keycloak or in the application), four elements must match on both sides:
| Element | What must match | Impact if wrong |
|---|---|---|
| Entity ID | Unique SP identity on both sides | Assertion rejected due to wrong audience |
| ACS URL | Where the SP receives the Response | Response never arrives, error at the SP |
| Name ID | Agreed user identity format | User recognized as a different identity |
| Attributes | Mapped attribute names | Application doesn't receive the data it needs |
Entity ID is the identity Keycloak uses as the audience value in the assertion. In Keycloak, this is filled in the Client ID field when creating the SAML client. Make sure the value is truly identical to what the SP expects — often a difference of a single letter or a trailing slash is enough to break the integration.
The Assertion Consumer Service URL is the address in the application that receives the Response from the browser. When creating the client in Keycloak, you put the ACS URL in Valid Redirect URIs. If the SP sends the URL without a trailing slash, you must register both variations so it doesn't fail.
Once the SP receives the assertion, the application maps the NameID to its internal account. That's why the NameID format must be consistent — if the SP expects email, the Name ID Format on the Keycloak client must be email, and the assertion must carry an email address matching the account in the application.
The same goes for attributes: SPs like Salesforce often ask for firstName, lastName, and email under specific names. You create a mapper in the Mappers tab of the SAML client for each attribute, then adjust the SAML attribute names to exactly what the SP documents.
When the integration fails, the first helpful step is to look at the assertion being sent. The most commonly used tools:
The recommended testing steps:
1. Enable SAML Tracer in the browser
2. Open the application URL (SP) then click login
3. Follow the redirect flow to the Keycloak login page
4. Log in with a valid user
5. In SAML Tracer, select the last Response request
6. Inspect the status, issuer, audience, NameID, and assertion attributesNote: the SAMLRequest from the SP appears on the way in, the SAMLResponse from the IdP appears on the way back. Both can be read raw in SAML Tracer.
When inspecting an assertion, the validation order is:
Tip
Before changing any configuration while debugging, first capture the failing assertion with SAML Tracer. One complete XML document is far more informative than reading server logs at random.
| Error shown | Common cause | Solution |
|---|---|---|
| Invalid signature | Signing key not in sync | Re-import the IdP metadata into the SP |
| Audience mismatch | Entity ID doesn't match | Make the audience equal to the SP's entity ID |
| Wrong NameID format | Format not agreed | Set the Name ID Format on the Keycloak client |
| ACS URL not registered | Redirect URI differs slightly | Add URL variations with and without the trailing slash |
| Assertion expired | Clock difference between servers | Synchronize NTP on all hosts |
| Attribute not delivered | Attribute names don't match | Match the mapper attribute names to the SP documentation |
A special note about signatures: after you rotate the signing key in Keycloak, assertions previously signed with the old key will be rejected by the SP. The solution is always the same — import the new IdP metadata into the SP.
In this episode 14, you connected real applications as SAML service providers to Keycloak: getting to know popular SPs, exchanging metadata both ways, matching entity ID, ACS URL, NameID, and attributes on both sides, testing the flow with SAML Tracer, and handling typical errors such as invalid signature and audience mismatch.
Key takeaways:
In the next episode (episode 15), we shift from authentication to identity storage: user federation — connecting Keycloak to LDAP and Active Directory so users don't have to be duplicated in every system.