Skip to content

Commit 269b49b

Browse files
committed
Streamline the passwords
1 parent c09079b commit 269b49b

8 files changed

+100
-15
lines changed

docker-compose.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ services:
2929
KC_LOG_LEVEL: info
3030
KC_METRICS_ENABLED: "true"
3131
KC_HEALTH_ENABLED: "true"
32-
KEYCLOAK_ADMIN: admin
33-
KEYCLOAK_ADMIN_PASSWORD: "${KEYCLOAK_ADMIN_PASSWORD}"
3432

3533
EXTERNAL_ORIGIN: "${EXTERNAL_ORIGIN:-http://localhost:9080}"
3634
ADMIN_EMAIL: "${ADMIN_EMAIL:[email protected]}"
35+
ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
3736
depends_on:
3837
- postgres
3938

docker/Dockerfile.keycloak

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1+
# Be sure to check https://github.com/keycloak/keycloak/blob/main/quarkus/container/Dockerfile
2+
# and bump the used UBI when bumping the image.
3+
# This is an ugly way to add jq and python3.
4+
5+
FROM registry.access.redhat.com/ubi9 AS ubi
6+
7+
RUN dnf install -y python3
8+
19
FROM keycloak/keycloak:25.0
210

11+
USER 0
12+
COPY --from=ubi /usr /tmp/usr
13+
RUN cp -arn /tmp/usr /
14+
RUN rm -rf /tmp/usr
15+
USER 1000
16+
317
COPY ./docker/keycloak-realm.json /etc/keycloak/realm.json
18+
COPY ./docker/keycloak-prepare-realm.py /usr/local/bin/keycloak-prepare-realm.py
419
COPY ./docker/keycloak-entrypoint.sh /usr/local/bin/entrypoint.sh
520

621
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
722

8-
CMD ["start", "--import-realm"]
23+
CMD ["start", "--import-realm"]

docker/keycloak-entrypoint.sh

+18-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,24 @@ if [ -z "$KC_HOSTNAME" ]; then
1313
fi
1414
fi
1515

16+
if [ -z "$KEYCLOAK_ADMIN" ]; then
17+
if [ -n "$ADMIN_EMAIL" ]; then
18+
export KEYCLOAK_ADMIN="$ADMIN_EMAIL"
19+
fi
20+
fi
21+
22+
if [ -z "$KEYCLOAK_ADMIN_PASSWORD" ]; then
23+
if [ -n "$ADMIN_PASSWORD" ]; then
24+
export KEYCLOAK_ADMIN_PASSWORD="$ADMIN_PASSWORD"
25+
fi
26+
fi
27+
1628
mkdir -p /opt/keycloak/data/import
17-
sed /etc/keycloak/realm.json \
18-
-e 's,{EXTERNAL_ORIGIN},'"$EXTERNAL_ORIGIN"',g' \
19-
-e 's,{ADMIN_EMAIL},'"$ADMIN_EMAIL"',g' \
20-
> /opt/keycloak/data/import/realm.json
29+
/usr/local/bin/keycloak-prepare-realm.py \
30+
--external-origin "$EXTERNAL_ORIGIN" \
31+
--admin-email "$ADMIN_EMAIL" \
32+
--admin-password "$ADMIN_PASSWORD" \
33+
</etc/keycloak/realm.json \
34+
>/opt/keycloak/data/import/realm.json
2135

2236
exec /opt/keycloak/bin/kc.sh "$@"

docker/keycloak-prepare-realm.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import json
5+
import sys
6+
import hashlib
7+
import base64
8+
import os
9+
10+
11+
ITERATIONS = 180000
12+
13+
14+
def main():
15+
parser = argparse.ArgumentParser()
16+
parser.add_argument("--external-origin", type=str, required=True)
17+
parser.add_argument("--admin-email", type=str, required=True)
18+
parser.add_argument("--admin-password", type=str, required=True)
19+
args = parser.parse_args()
20+
21+
realm = json.load(sys.stdin)
22+
23+
# Replace admin email placeholder
24+
for user in realm.get("users", []):
25+
if user.get("id") == "admin":
26+
user["username"] = args.admin_email
27+
user["email"] = args.admin_email
28+
29+
# Update password credentials
30+
for credential in user.get("credentials", []):
31+
if credential.get("type") == "password":
32+
# Generate a random salt
33+
salt = os.urandom(16)
34+
salt_b64 = base64.b64encode(salt).decode('utf-8')
35+
36+
# Hash the password with the salt
37+
pwd_hash = hashlib.pbkdf2_hmac('sha256', args.admin_password.encode('utf-8'), salt, ITERATIONS)
38+
pwd_hash_b64 = base64.b64encode(pwd_hash).decode('utf-8')
39+
40+
# Set credential data in Keycloak format
41+
credential["credentialData"] = json.dumps({"hashIterations": ITERATIONS, "algorithm": "pbkdf2-sha256"})
42+
credential["secretData"] = json.dumps({"salt": salt_b64, "value": pwd_hash_b64})
43+
44+
# Replace EXTERNAL_ORIGIN placeholders in clients
45+
for client in realm.get("clients", []):
46+
# Update redirectUris
47+
if "redirectUris" in client:
48+
client["redirectUris"] = [uri.replace("{EXTERNAL_ORIGIN}", args.external_origin)
49+
for uri in client["redirectUris"]]
50+
51+
# Update webOrigins
52+
if "webOrigins" in client:
53+
client["webOrigins"] = [origin.replace("{EXTERNAL_ORIGIN}", args.external_origin)
54+
for origin in client["webOrigins"]]
55+
56+
# Output the modified realm configuration
57+
json.dump(realm, sys.stdout, indent=2)
58+
59+
60+
if __name__ == "__main__":
61+
main()

docker/keycloak-realm.json

-2
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,10 @@
8888
"id": "password",
8989
"type": "password",
9090
"userLabel": "My password",
91-
"createdDate": 1726948946561,
9291
"secretData": "{\"value\":\"oRgPShutFloqamI75qmIrgwLErxpQQsBQTMzD0Rma8Q=\",\"salt\":\"1K/UNtNh0Ao7sO8iKZBpiQ==\",\"additionalParameters\":{}}",
9392
"credentialData": "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
9493
}
9594
],
96-
"requiredActions": ["UPDATE_PASSWORD"],
9795
"realmRoles": ["ozmadb-admin", "default-roles-ozma"]
9896
}
9997
]

env.dev.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
2-
KEYCLOAK_ADMIN_PASSWORD=admin
2+
ADMIN_PASSWORD=admin

env.production.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
22
# Set this to a secret password
3-
KEYCLOAK_ADMIN_PASSWORD=
3+
ADMIN_PASSWORD=
44
# Replace example.com in the following two variables with your domain name
55
CADDY_ADDRESS=example.com
66
EXTERNAL_ORIGIN=https://example.com

render.yaml

+2-4
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,6 @@ services:
7272
value: 'true'
7373
- key: KC_HEALTH_ENABLED
7474
value: 'true'
75-
- key: KEYCLOAK_ADMIN
76-
value: admin
77-
- key: KEYCLOAK_ADMIN_PASSWORD
78-
generateValue: true
7975
- key: EXTERNAL_PROTOCOL
8076
value: https
8177
- key: EXTERNAL_HOSTPORT
@@ -85,6 +81,8 @@ services:
8581
envVarKey: DOMAIN
8682
- key: ADMIN_EMAIL
8783
sync: false
84+
- key: ADMIN_PASSWORD
85+
generateValue: true
8886

8987
- name: ozmadb
9088
type: pserv

0 commit comments

Comments
 (0)