This provider encrypts user attribute values before storing them to the database and decrypt them upon loading from the database. This is to address data security regulations such as GDPR that require any PII data to not be stored in plain/raw format at rest.
Git clone this repo:
git clone https://github.com/MLukman/Keycloak-PII-Data-Encryption-Provider.git Keycloak-PII-Data-Encryption-Provider
cd Keycloak-PII-Data-Encryption-Provider
Compile this provider into a JAR file using the following command. JDK 17 or above and Maven are required to be pre-installed on the machine.
mvn clean package
Copy paste the packaged JAR file from inside target
folder into Keycloak's providers
folder. Run kc.sh build
command to get Keycloak to register this provider.
Use this method if this provider needs to be pre-packaged inside a custom Keycloak Docker image. Below is a sample Dockerfile:
# ARG defined before FROM in multi-staged Dockerfile is shared among the stages
ARG KEYCLOAK_VERSION=25.0.4
# Build the provider
FROM maven:3.8.1-openjdk-17-slim AS keycloak-pii-data-encryption
ARG KEYCLOAK_VERSION # Dockerfile peculiarity that requires ARG defined before FROM to be re-declared afterwards if we want to use instead the stage
WORKDIR /app
RUN apt-get update && apt-get install -y git && apt-get clean
RUN git clone https://github.com/MLukman/Keycloak-PII-Data-Encryption-Provider.git .
RUN mvn clean package -Dkeycloak.version=$KEYCLOAK_VERSION
################################################################################
# Base image from official keycloak
FROM quay.io/keycloak/keycloak:$KEYCLOAK_VERSION
# Add provider JAR
COPY --from=keycloak-pii-data-encryption /app/target/*.jar /opt/keycloak/providers
# Need to build after adding providers
RUN /opt/keycloak/bin/kc.sh build
This provider requires the encryption key to be provided via environment variable KC_PII_ENCKEY
. There is, however, a default fallback that uses MD5 hash of environment variable KC_DB_URL
if the encryption key is not provided. If you rely on this fallback and in the future need to migrate your Keycloak data into another databases that results in a different value of KC_DB_URL
, you need to get the old value of KC_DB_URL
, encode it using lowercased MD5 hash and set the value to the KC_PII_ENCKEY
environment variable.
Enabling the encryption for a specific user attribute is as simple as adding the custom validator of type pii-data-encryption
inside the "Create attribute" or "Edit attribute" form of that attribute in the admin console.
This provider also automatically encrypts any user attributes that have their names start with "pii-" prefix even without the validator.
Browse the Keycloak database using any tool (e.g. phpMyAdmin for MySQL database) and navigate to the table USER_ATTRIBUTE
. Verify that the column VALUE
for the rows corresponding to user attributes that have been the encryption enabled will contain Base-64 strings that start with $$$
, like below:
- Built-in user attributes
username
andemail
as well as unmanaged attributes are not supported. - If the encrypted values in the database cannot be decrypted for whatever reason, the base64 encrypted value will be displayed as-is to the users and clients. This may cause confusions.
- The encryption is only applied to user attributes when they are updated by the users after the encryption setting is enabled in the admin console. Until they are updated, their values remain unencrypted in the database. (Idea for future enhancement: to allow admins to force encryption/decryption of existing attributes upon enabling/disabling the encryption setting)