Configuring Keycloak as a SAML Identity Provider: creating a SAML client, exporting metadata, configuring signing and encryption keys, choosing the NameID format, mapping attributes, and preparing the ACS and SLS endpoints for integration with applications.

In episode 12 you understood the SAML foundation: assertions, bindings, the SP-initiated and IdP-initiated flows, and the XML structure. Episode 13 translates that theory into real configuration: turning Keycloak on as a SAML Identity Provider. You'll create a SAML client, export metadata, configure signing and encryption keys, choose the NameID format, map attributes, then test the flow — before we hook up a real application as a service provider in episode 14.
When you create a client with the SAML type in a realm, Keycloak immediately acts as the IdP for that application. This isn't a special mode; the same realm can serve OIDC and SAML clients at once. The only difference is how the application asks for it — through the XML-based SAML protocol rather than the OIDC token endpoint.
From the SP's point of view, Keycloak exposes three important things:
/realms/{realm}/protocol/saml.First steps in the admin console:
1. Open the Clients tab in a realm and click Create client
2. Select Client type SAML, and fill Client ID with the SP's entity ID
3. In the Settings tab, fill Valid Redirect URIs with the application's ACS URL
4. Choose the Name ID Format agreed with the SP
5. Configure signing and encryption options per the SP's requirements
6. Save the configurationIn modern Keycloak, the client type is chosen from the Client type dropdown with the value saml. The options you'll find in the Settings tab: Sign Assertions, Sign Documents, Require Assertion Signature, Encrypt Assertions, Force POST Binding, and Assertion Signature Algorithm. Don't turn everything on without understanding it — each option must match the SP's capabilities.
Rule of thumb: always enable Sign Assertions; enable Encrypt Assertions only when the SP demands it, because encryption adds complexity to the key exchange.
Once the client is created, Keycloak provides the complete realm metadata at the endpoint:
realms/demo/protocol/saml/descriptor
This is the document you give to the SP as a complete description of the IdP's capabilities — including the public key used to verify signatures. Its snippet looks roughly like this:
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://keycloak.example.com/realms/demo">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Certificate>MIIC...</ds:X509Certificate>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://keycloak.example.com/realms/demo/protocol/saml"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://keycloak.example.com/realms/demo/protocol/saml"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>Keycloak uses the realm key to sign assertions and can export it via the Realm Keys tab in the admin console. Remember: every time you rotate the signing key, the metadata already held by the SP must be updated — otherwise all SPs will fail to verify the signature.
In the Settings tab of the SAML client, you configure the key points that determine how the SP talks to the IdP:
For encryption, Keycloak supports encrypting assertions with the XML Encryption standard. The SP's public key is taken from metadata, then the assertion is encrypted before being sent. You'll need this when the SP requires encrypted assertions.
| Integration Option | How it works | Suitable for | Drawback |
|---|---|---|---|
| Import SP metadata | Admin uploads the SP's XML metadata to Keycloak | Modern SPs that provide metadata | Depends on the quality of the provided metadata |
| Manual configuration | Fill entity ID, ACS URL, and attributes by hand | SPs without metadata support | Prone to typos, requires high care |
NameID is the user identity carried by the assertion. Its format options are set through the Name ID Format field on the client:
email — suitable when email is the primary identity at the SP.persistent — an identifier that doesn't change for the user's lifetime, suitable for cross-organization federation.transient — a one-time identifier, for sessions that don't need to be linked across visits.username — the user name in the Keycloak realm.Force Name ID Format forces the assertion to always use the selected format, ignoring what the SP requests in the AuthnRequest.
Attributes in the assertion are managed via the Mappers tab on the client. Each mapper maps one Keycloak user attribute to a SAML attribute name carried by the assertion:
Important
Metadata is the contract between IdP and SP. Change the signing key or add attributes, then update the metadata held by the SP. Most SAML integration failures originate from stale metadata.
Once the client is configured, test it by browsing the SP application and pressing login. Several points to always check when the flow fails:
Realm events in Keycloak can be used to observe the flow: the admin console records logins and failures related to this SAML client.
In this episode 13, you turned Keycloak on as a SAML IdP: creating a SAML client, understanding the SSO and SLS endpoints, exporting complete metadata with the signing key, configuring encryption and signature algorithms, choosing the NameID format, mapping attributes through mappers, and knowing the main troubleshooting points.
Key takeaways:
saml type makes Keycloak an IdP without changing the same realm used for OIDC.realms/demo/protocol/saml/descriptor endpoint contains everything the SP needs.In the next episode (episode 14), we flip sides: Keycloak is ready as an IdP, now you connect a real SAML service provider — Salesforce, Google Workspace, or a Jira application — including how to test assertions with SAML Tracer and handle typical integration errors.