---
type: how-to
title: Keycloak
summary: "Gate Keycloak login, password reset, and registration with Caputchin: install the extension, pick a render mode, and verify the token server-side."
---

Keycloak is a server, not a page you embed a script on, so Caputchin ships as a Keycloak **extension**: a provider JAR you drop into Keycloak. It renders the Caputchin widget on the login, password-reset, and registration pages, and verifies the token from inside Keycloak before the flow proceeds. Both the checkbox widget and the game work.

The extension is open source. The full reference (every config property, the realm-export JSON, the theme contract, and a compatibility matrix) lives in the repository: [github.com/Caputchin/caputchin-keycloak](https://github.com/Caputchin/caputchin-keycloak).

<Callout type="info">
Works with Keycloak 26.x (the Quarkus distribution). You need access to the Keycloak deployment to add a provider JAR and run `kc.sh build`; this is not a hosted marketplace app.
</Callout>

## 1. Install the extension

Build the provider JAR and place it in Keycloak, then rebuild:

```bash
# build (no JDK on the host? run it in Docker)
docker run --rm -v "$PWD":/work -w /work maven:3.9-eclipse-temurin-21 mvn -DskipTests package

cp target/caputchin-keycloak.jar "$KEYCLOAK_HOME/providers/"
"$KEYCLOAK_HOME/bin/kc.sh" build
"$KEYCLOAK_HOME/bin/kc.sh" start --optimized
```

`kc.sh build` is required for Keycloak to discover the providers.

## 2. Pick how the widget renders

There are two ways, and you choose per realm.

### Turnkey: the bundled theme (no custom theme needed)

The JAR ships a `caputchin` login theme. Set it under **Realm Settings → Themes → Login theme: `caputchin`**, and the widget renders on the login, reset, and registration pages with no template editing. This is the fastest path if you use a stock Keycloak login.

### Headless: your own theme renders the widget

If you ship a custom login theme (for example a Keycloakify React theme), keep your theme and run the extension headless. It exposes the widget configuration into the page context and validates the token; your theme renders the `<caputchin-widget>` (or `<caputchin-game>`) element and styles it with your design tokens. The token field is `caputchin-token`. The full attribute contract and a Keycloakify example are in the [repository theme guide](https://github.com/Caputchin/caputchin-keycloak/blob/main/docs/theme-contract.md).

## 3. Bind it to your flows

In **Authentication → Flows**, duplicate the flow you want to protect and swap the execution:

| Flow | Set the execution to |
| --- | --- |
| Browser (login) | Caputchin Username Password Form |
| Reset Credentials | Caputchin Reset Credential - Choose User |
| Registration | add Caputchin to the registration form |

The login and reset challenges render on the same page as the credentials, not as a separate step. Open each execution's config (the gear) to set your keys. Do not add a challenge to the direct-grant flow: there is no browser there, so it would break API token requests.

## 4. Configure the keys

In the execution config, set:

- **Site key**: your public key (`cpt_pub_...`). The only value sent to the browser.
- **Secret key**: your secret (`cpt_sec_...`). You can store it as a literal, point at an environment variable (so it never lands in your realm export), or use a `${vault.*}` reference.
- **Widget mode**: `checkbox`, `invisible`, or `game`. Plus size, locale (defaults to following the realm locale), and skin.
- **Fail closed**: on by default, so a verify outage blocks rather than letting bots through.

The richer look (which game, skins, brand) is set once in the [Caputchin dashboard](https://caputchin.com) on the site key itself, so you do not repeat it here.

## 5. Allow the widget in your Content Security Policy

Keycloak's default login CSP is stricter than the widget needs. Under **Realm Settings → Security Defenses → Content Security Policy**, allow the loader script, the verify host, and WebAssembly. The exact value is in the [repository CSP guide](https://github.com/Caputchin/caputchin-keycloak/blob/main/docs/csp.md).

<Callout type="info">
The server-side verification (Keycloak to the verify host) is a server-to-server call and is not affected by the browser CSP. Only the browser-side widget traffic is.
</Callout>

## Try it locally

The repository includes a one-command local Keycloak (`e2e/`) wired to a local Caputchin stack, so you can click through all three gated flows before deploying. See the [repository README](https://github.com/Caputchin/caputchin-keycloak).
