Integration guides

Keycloak

View as Markdown

Keycloak is a server, not a page you embed a script on, so Caputchin ships as a Keycloak extension: a provider JAR you add to Keycloak. It renders the Caputchin widget on the login, password-reset, and registration pages, and verifies the token from inside Keycloak before the flow continues. 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. Plan on about 15 minutes from a new account to the first server-verified session.

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, and an admin account for the realm you protect.

1. Create a site key

Sign in at caputchin.com/login (your first sign-in creates the account), open your Personal troop, click Create site-key, name it after your Keycloak realm, and click Create. Copy both values:

  • the public key (cpt_pub_...),
  • the secret (cpt_sec_...). It is shown only once.

Create your account and first site key walks through the same screens with more detail.

2. Install the extension

Download caputchin-keycloak.jar from the latest release, copy it into Keycloak's providers/ directory, and rebuild:

cp 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. In a container image, copy the JAR and run the build in the image:

FROM quay.io/keycloak/keycloak:26.4
COPY caputchin-keycloak.jar /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh build

To build the JAR from source instead, see the repository install guide.

3. Give Keycloak the secret

Keep the secret out of the realm configuration: set it as an environment variable on the Keycloak server, for example CAPUTCHIN_SECRET, and restart Keycloak. In step 5 you enter only the variable's name. A literal secret or a ${vault.*} reference also works; see the repository configuration guide.

4. Pick how the widget renders

There are two ways, and you choose per realm.

Turnkey: the bundled theme

The JAR ships a caputchin login theme. In the Admin Console, open your realm, go to Realm settings → Themes, set Login theme to caputchin, and click Save. 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. The token field is caputchin-token. The full attribute contract and a Keycloakify example are in the repository theme guide.

5. Bind it to the login flow

Keycloak does not change a step's authenticator in place, so you add the Caputchin step to a copy of the flow and remove the original step.

  1. Go to Authentication. On the browser flow, open the menu (⋮), click Duplicate, name the copy (for example browser caputchin), and click Duplicate.

  2. In the copy, find the forms sub-flow. Click its + (Add) button, choose Add execution, select Caputchin Username Password Form, and click Add.

  3. Drag the new step to the top of the forms sub-flow, above the Conditional 2FA sub-flow, so it runs where the old step ran. Its requirement is Required.

  4. Delete the original Username Password Form step from the forms sub-flow.

  5. Click the gear (Settings) on the Caputchin step and fill in:

    • Alias: any name, such as caputchin-login.
    • Site key: your public key (cpt_pub_...), the only value sent to the browser.
    • Secret key env var: the variable name from step 3, such as CAPUTCHIN_SECRET.

    Then click Save. The other fields have working defaults: Widget mode checkbox (or invisible, or game), Locale kc (follows the realm locale), and Fail closed on, so a verify outage blocks sign-ins instead of letting them through.

  6. Open the flow's Action menu, click Bind flow, keep Browser flow, and click Save.

The challenge renders on the same page as the credentials, not as a separate step. With the default settings, the check runs when the user clicks Sign In.

Password reset and registration

The same pattern protects the other two forms:

FlowAdd this stepIn place of
Reset credentialsCaputchin Reset Credential - Choose UserChoose User
RegistrationCaputchin, in the registration form sub-flow, set to Required(added alongside Registration User Creation)

Each Caputchin step has its own settings (gear), so enter the site key and secret variable on each. Do not add a challenge to the direct-grant flow: there is no browser there, so it would break API token requests. Binding to flows in the repository shows the same setup as realm-export JSON.

The richer look (which game, skins, brand) is set once in the Caputchin dashboard on the site key itself, so you do not repeat it in Keycloak.

6. Check the Content Security Policy

Keycloak's default login Content Security Policy (under Realm settings → Security defenses → Headers) is frame-src 'self'; frame-ancestors 'self'; object-src 'none';. It restricts frames, not scripts or connections, and the game runs in a srcdoc frame, so the checkbox, the invisible widget, and the game all work with it unchanged.

If you set a stricter policy of your own, start from the one in the repository CSP guide. A script-src directive also applies to Keycloak's own inline scripts, so test the login page and the Account Console after any change.

The server-side verification (Keycloak to the verify host) is a server-to-server call and is not affected by the browser policy.

7. Confirm the first server-verified session

  1. Open your application's login (or the realm's login page) in a private window.
  2. Sign in with a test user. The widget runs when you click Sign In, and Keycloak signs you in.
  3. In the Caputchin dashboard, open your troop and click your site key. Refresh the statistics.

Server-verified now reads at least 1: Keycloak confirmed a token with Caputchin. That is your first verified session. If the login page shows "Verification failed. Please complete the check and try again." and Server-verified stays at 0, the token never reached Keycloak: check the browser console for a Content Security Policy error (step 6). If Client-completed went up but sign-in still fails, check that the secret variable from step 3 is set on the server. Statistics and sessions explains each number.

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.

See also