This Keycloak extension enables generating, registering, and verifying TOTP (Time-Based One-Time Password) credentials via API. It provides a set of endpoints to manage TOTP credentials for users programmatically.
- Generate TOTP secrets and QR codes
- Register TOTP credentials for users
- Verify TOTP codes
Tested on Keycloak 25
This project uses Gradle for building. To build the project, follow these steps:
- Clone this repository:
git clone https://github.com/medihause/keycloak-totp-api.git cd keycloak-totp-api
- Build the project using the
shadowJar
task:./gradlew shadowJar
This will create a JAR file in the build/libs
directory.
- Go to the Releases page of this repository.
- Download the latest release, making sure to choose the JAR file with the 'all' suffix (e.g.,
keycloak-totp-api-1.0.0-all.jar
), as it includes all necessary dependencies.
-
Copy the downloaded JAR file to the
providers
folder in your Keycloak installation directory. -
Run the following command to build Keycloak with the new extension:
${KEYCLOAK_HOME}/bin/kc.sh build
When using Docker, you need to make the extension available to the Keycloak container. You can do this by:
-
Mounting the JAR file into the container:
Add this volume mount to your Docker run command or docker-compose file:
-v /path/to/keycloak-totp-api-1.0.0-all.jar:/opt/keycloak/providers/keycloak-totp-api-1.0.0-all.jar
OR
-
Copying the JAR file into a custom Docker image:
If you're building a custom Keycloak image, add this line to your Dockerfile:
COPY keycloak-totp-api-1.0.0-all.jar /opt/keycloak/providers/
After adding the extension, make sure to build the Keycloak image if you're using a custom Dockerfile.
Generates a new TOTP secret and QR code for a user.
- Method: GET
- URL:
{{BASE_URL}}/realms/{{REALM}}/totp-api/{{USER_ID}}/generate
- Response:
The
{ "encodedSecret": "OFIWESBQGBLFG432HB5G6TTLIVIEGU2O", "qrCode": "iVBO...." }
qrCode
is a base64-encoded image.
Registers a TOTP credential for a user.
- Method: POST
- URL:
{{BASE_URL}}/realms/{{REALM}}/totp-api/{{USER_ID}}/register
- Request Body:
Set
{ "deviceName": "DeviceOne", "encodedSecret": "OFIWESBQGBLFG432HB5G6TTLIVIEGU2O", "initialCode": "128356", "overwrite": true }
overwrite
totrue
to replace an existing TOTP credential. - Response:
{ "message": "TOTP credential registered" }
Verifies a TOTP code for a user.
- Method: POST
- URL:
{{BASE_URL}}/realms/{{REALM}}/totp-api/{{USER_ID}}/verify
- Request Body:
{ "deviceName": "DeviceOne", "code": "866359" }
- Response:
{ "message": "TOTP code is valid" }
All API requests must be authenticated. The requester must:
- Be authenticated and provide a valid bearer token.
- Be a service account.
- Have the
manage-totp
realm role.