--- title: Keycloak --- # Keycloak Official CaptchaLa plugin for Keycloak. Adds a CAPTCHA challenge to Keycloak's built-in login, registration and reset-password screens, verified server-side, without writing any code. Ships as a single provider JAR you drop into Keycloak. ## What it covers Each flow below is wired in as a separate authentication step — you protect only the screens you want. - Browser login (the username / password form) - Self-registration - Reset password (the "forgot password" screen) The challenge renders as a floating widget by default (`float`), or as a click-to-open modal (`popup`). ## Install ### 1. Get the JAR The plugin is open source at [**github.com/Captcha-La/captchala-keycloak**](https://github.com/Captcha-La/captchala-keycloak). Two options: - **Download the release** (recommended) — grab `keycloak-captchala-.jar` from the repository's Releases page. - **Build from source** — `git clone` the repo and run `mvn clean package`; the JAR is produced under `target/`. The plugin targets Keycloak ≥ 26 (Quarkus) and Java 17. ### 2. Deploy it ```bash cp keycloak-captchala-1.0.0.jar /opt/keycloak/providers/ /opt/keycloak/bin/kc.sh build # restart Keycloak ``` Then set the login theme: **Realm settings → Themes → Login theme → `captchala`**. ### 3. Get your keys Sign up at [`dash.captcha.la`](https://dash.captcha.la), create an application, then copy: - **App Key** — public, embedded in the page - **App Secret** — server-side only, used by Keycloak to mint a one-time token and call `/v1/validate` ### 4. Wire the flows In the admin console, add the matching execution to each flow you want protected, then click the gear icon to paste your **App Key** and **App Secret**: - **Browser login** — duplicate the *browser* flow, replace **Username Password Form** with **Captchala Username Password Form** (REQUIRED), bind it as the realm browser flow. - **Registration** — duplicate the *registration* flow, add **Captchala Registration** (REQUIRED) to the registration-form sub-flow, bind it as the realm registration flow. - **Reset password** — duplicate the *reset credentials* flow, replace **Choose User** with **Captchala Reset Credential (choose user)** (REQUIRED), bind it as the realm reset-credentials flow. Open one of the protected screens in a private window to confirm the challenge renders. ## Configuration Every execution is configured independently from its gear icon. The defaults work out of the box once the keys are set. | Setting | Key | Default | Description | | --- | --- | --- | --- | | App Key | `app.key` | — | Public key from the CaptchaLa dashboard. Required. | | App Secret | `app.secret` | — | Server secret. Required. Stored masked, never exposed to the browser. | | API base URL | `api.base` | `https://apiv1.captcha.la` | CaptchaLa API base. | | Widget script URL | `script.url` | `https://api.captcha.la/sdk/jslib/captchala.js` | Where the widget JS loads from. | | Widget CSS URL | `css.url` | `https://api.captcha.la/sdk/jslib/captchala.css` | Where the widget CSS loads from. | | Render mode | `product` | `float` | `float` (floating widget) or `popup` (modal). | | Action label | `action` | per flow | The `action` sent on validation (`login`, `register`, `reset`). | | Language | `language` | realm locale | Widget language; blank follows the Keycloak locale. | | Fail closed | `fail.closed` | `true` | When the CaptchaLa API is unreachable, deny the submission. Turn off to fail open. | | Use server token | `use.server.token` | `true` | Mint a one-time server token at render for stronger anti-replay. | ## FAQ **Is the plugin free?** Yes. The Keycloak plugin is free and open source. The CaptchaLa free plan covers 10,000 verifications a month — paid plans only apply if you need more volume. **Which Keycloak versions are supported?** Keycloak 26+ on the Quarkus distribution, built against 26.5.6 with Java 17. Drop the JAR into `providers/`, run `kc.sh build`, and restart. **Which screens can it protect?** Browser login, self-registration, and reset password. Each is added to its flow independently, so you can protect one, two, or all three. **Is the App Secret ever exposed to the browser?** No. The secret is stored masked and is only ever sent in the `X-App-Secret` header from Keycloak to the CaptchaLa API. It never appears in any page, template, or log. Each challenge is verified with a single-use token, so a solved token can't be replayed. **What happens if the CaptchaLa API is unreachable?** By default the plugin fails closed (the submission is denied). Set `fail.closed` to off on any execution to fail open instead — useful for staged rollout, not recommended for production. ## Source - Plugin repository: [`github.com/Captcha-La/captchala-keycloak`](https://github.com/Captcha-La/captchala-keycloak) - Releases (JAR): [`github.com/Captcha-La/captchala-keycloak/releases`](https://github.com/Captcha-La/captchala-keycloak/releases) - Issues / feature requests: filed against the repository above - Related: [Web SDK](/web-sdk) · [API Reference](/api-reference)