Read secrets from files
See original GitHub issueDescription
For passing sensitive information (database password) to a Keycloak container, it would be useful to support a file-based solution in addition to the plain environment variables.
Postgres image, for example supports it like this:
As an alternative to passing sensitive information via environment variables, _FILE may be appended to some of the previously listed environment variables, causing the initialization script to load the values for those variables from files present in the container. In particular, this can be used to load passwords from Docker secrets stored in /run/secrets/<secret_name> files.
docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d postgres
I am creating my own image based on the official one and have a custom entrypoint to implement this.
#!/bin/bash
# Basic support for passing the db password as a mounted file. Or any other KC_ variable,
# really.
# Looks up environment variables like KC_*_FILE, reads the specified file and exports
# the content to KC_*
# e.g. KC_DB_PASSWORD_FILE -> KC_DB_PASSWORD
# Find suitable variables
lines=$(printenv | grep -o KC_.*_FILE)
# Split into array
vars=($lines)
# Enumerate variable names
for var in ${vars[@]}; do
# Output variable, trim the _FILE suffix
# e.g. KC_DB_PASSWORD_FILE -> KC_DB_PASSWORD
outvar="${var%_FILE}"
# Variable content = file path
file="${!var}"
# Empty value -> warn but don't fail
if [[ -z $file ]]; then
echo "WARN: $var specified but empty"
continue
fi
# File exists
if [[ -e $file ]]; then
# Read contents
content=$(cat $file)
# Export contents if non-empty
if [[ -n content ]]; then
export $outvar=$content
echo "INFO: exported $outvar from $var"
# Empty contents, warn but don't fail
else
echo "WARN: $var -> $file is empty"
fi
# File is expected but not found. Very likely a misconfiguration, fail early
else
echo "ERR: $var -> file '$file' not found"
exit 1
fi
done
# Pass all command parameters
/opt/keycloak/bin/kc.sh start "$@"
In my Dockerfile
, I simply include the script and set it as the entrypoint.
COPY entrypoint.sh .
ENTRYPOINT ["/entrypoint.sh"]
This enables me to run it locally like:
docker run --mount type=bind,source=$(pwd)/secret,target=/tmp/kcdbpw -e KC_DB_PASSWORD_FILE=/tmp/kcdbpw my-keycloak
And enables using Docker Secrets for actual production use in pretty much equivalent manner.
This is an acceptable solution, but it would be nice to have first-class support for this kind of behavior.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:8
- Comments:17 (9 by maintainers)
Top GitHub Comments
I have to disagree @andreaTP, this requirement is not specific to Docker Swarm. For instance, Hashicorp Nomad uses an equivalent way to mount secrets (https://www.nomadproject.io/docs/runtime/environment#secrets).
Also, this was supported in 16.0 and is still presented in the main readme at https://hub.docker.com/r/jboss/keycloak. Obviously I have no usage statistics, but one might assume that it was previously added because someone else than me needed it. 😃
@epuronta we discussed this subject internally in the Keycloak team, this is the result:
Vault
feature works in Keycloakbash
scripts of the distributionI want to express my profound respect and appreciation for how you handled this conversation despite the different POV. Unfortunately, the action here is to:
I can guarantee that your concerns and requests have been heard and will be considered as soon as the team works on this, thanks for being such a valuable community member ❤️