To safeguard registration against bots, Keycloak has integration with Google reCAPTCHA. This extension provides similar functionality, but with a more privacy friendly provider named ALTCHA. The code is based the hCaptcha extension, itself based on the vanilla implementation of reCAPTCHA in Keycloak.
ALTCHA is a proof-of-work captcha generator which generates a complex math challenge taking a few seconds for a computer to solve, thus hindering exploitation of the form by spambots. The CAPTCHA doesn’t need any user interaction and is therefore accessible for disabled people.
This implementation doesn’t make any third-party call whatsoever. The Keycloak extension is using the server-side Java implementation of ALTCHA and generates the challenge by itself. A small Javascript snippet is needed to solve the challenge client-side.
Download the latest JAR from the Releases section of our Gitea repository or compile the JAR, then drop it into your_keycloak_installation/providers.
There are a few steps you need to perform in the Keycloak Admin Console.
- Click the Authentication left menu item and go to the Flows tab.
- Search for the flow named Registration, click on the options dropdown at the right and click on Duplicate. Give it whatever name you want.
- Click on the flow to see its steps.
- On the parent step named
<flow name> registration form, click the « + » icon and select Add step. - Select ALTCHA in the list and click Add.
- Set the ALTCHA step requirement from Disabled to Required.
- Click the gear icon at the right of the ALTCHA step, then fill the following information:
- Give it a name (
altchais fine) - In the ALTCHA HMAC Secret field, write a random string (the longer, the better). This key will be used to sign and verify captcha challenges.
- In the Complexity field, use a value comprised between 100 000 and 1 500 000 rounds. Write it without spaces and ensure that the chosen integer is positive. See ALTCHA docs for more details.
Here’s a valid configuration example:
Now, you need to make changes on your current theme or create a new theme. Please refer to the Keycloak documentation to create or edit your own theme.
You will need to edit the login/register.ftl template file and add the following lines after the <@registerCommons.termsAcceptance/> if block:
<#if altchaRequired??>
<altcha-widget challengejson='${altchaPayload}' <#if altchaFloating?? && altchaFloating=="true">floating</#if> hidefooter delay="2000" auto="onload" expire="3600000"></altcha-widget>
</#if>You can customize the widget settings following the documentation. Beware that you cannot edit the expire setting yet (see #1).
Then, save the following into the login/resources/js folder:
curl -o altcha.min.js https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/altcha.min.js
curl -o altcha-i18n.min.js https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist_i18n/all.min.js
You will have to update those files manually, monitor this Releases channel for security updates. Beware of breaking changes.
Create a new file in the js/ folder named altcha-import.js, containing the following:
import("./altcha.min.js")
import("./altcha-i18n.min.js")In the theme.properties file, add js/altcha-import.js into the scripts= setting. Do not add the minified JS file in the list: as a module, it needs to be imported by the intermediate file you created.
- In the Authentication left menu item, Flows tab, click on the options dropdown of your custom registration flow and click on Bind flow.
- Finally, enable registration : go to Realm settings, Login tab, and toggle User registration on.
And that’s it!
Clone the repository:
git clone https://git.lacontrevoie.fr/lacontrevoie/keycloak-altcha/Inside the repository, compile it using Maven with Java 17:
mvn clean compile packageYou can instruct Maven to use a specific Java version by prepending the JAVA_HOME environment variable:
JAVA_HOME=/usr/lib/jvm/java-17-openjdk/ mvn clean compile packageYou will get two JAR files in the target/ folder. The one you’re looking for is keycloak-altcha-jar-with-dependencies.jar.
This project is maintained by La Contre-Voie for internal use and is meant to be shared with anyone who needs it.
We need money to pay people to maintain this project, among others. If you are using this work and can afford it, please consider donating.

