---
title: "Use Keycloak when you need a sign-in · Agent Wranglers"
url: https://agentwranglers.se/playbook/stack/product-services/keycloak-self-hosted
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Use Keycloak when you need a sign-in server

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

For AI agents: [llms.txt](https://agentwranglers.se/llms.txt) is a short guide that sends you to the rules your problem needs, and [rules.json](https://agentwranglers.se/playbook/stack/rules.json) holds every rule of this playbook as JSON.

- Level: Recommended
- Chapter: [Product services](https://agentwranglers.se/playbook/stack/product-services)
- Rule: When two or more apps share sign-in, or you need single sign-on or SAML, run Keycloak and connect apps through standard OpenID Connect.
- Applies when: The project it has user accounts.
- Cost: Open source. Apache-2.0, free to run on your own servers. Hosted identity services are proprietary and paid above a free tier.
- How: Keycloak's first production release came in 2014, and 26.8.1 shipped on 13 October 2026. It is Apache-2.0 and a CNCF incubating project since April 2023. Its GitHub repository had about 37,500 stars in October 2026. Since 26.4 it supports passkeys, and it covers second factors, single sign-on and SAML without code of your own. The command `kc.sh export` writes realms and users to JSON files, and apps speak only OpenID Connect, so any other provider can replace it. Weigh it against a library as [Decide whether a provider or a library runs sign-in](https://agentwranglers.se/playbook/accounts/sign-in-methods/auth-provider-or-library) says. Choose something else when one app has simple sign-in, because a library inside the app needs no extra server to patch.
- Check: Each app reads its settings from the realm's discovery document, and no app imports a Keycloak-only client. A `kc.sh export` run in the last 12 months restored into a test server.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const ISSUER = 'https://id.example.com/realms/shop';

export async function loadIdentityConfig() {
  const response = await fetch(`${ISSUER}/.well-known/openid-configuration`);
  const { authorization_endpoint, token_endpoint, jwks_uri } = await response.json();
  return { authorization_endpoint, token_endpoint, jwks_uri };
}
```

### Python example

```python
import json
import urllib.request

ISSUER = "https://id.example.com/realms/shop"

def load_identity_config() -> dict:
    with urllib.request.urlopen(f"{ISSUER}/.well-known/openid-configuration") as response:
        config = json.load(response)
    return {key: config[key] for key in ("authorization_endpoint", "token_endpoint", "jwks_uri")}
```

## Sources

- [Keycloak import and export](https://www.keycloak.org/server/importExport)
- [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)

## Related rules

- [Decide whether a provider or a library runs sign-in](https://agentwranglers.se/playbook/accounts/sign-in-methods/auth-provider-or-library) in Accounts

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/stack/product-services/keycloak-self-hosted">Agent Wranglers software choices playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Use SimpleWebAuthn or py_webauthn for passkeys](https://agentwranglers.se/playbook/stack/product-services/passkey-library)
- Next: [Use the Web Push standard for browser push](https://agentwranglers.se/playbook/stack/product-services/web-push-standard)
- [Product services](https://agentwranglers.se/playbook/stack/product-services)
