Problem
When a container is started with MASTER_SERVER and OPENDJ_REPLICATION_TYPE, bootstrap/replicate.sh prints its whole environment to stdout before it sets up replication (replicate.sh#L23-L24):
# Comment out
echo "replicate ENV vars:"
env
ROOT_PASSWORD is part of that environment, so the Directory Manager password ends up in the container log. The log is exactly where it should not be: docker logs, kubectl logs and whatever log shipper collects them.
Reproduced with openidentityplatform/opendj:latest (2026-07-17):
docker network create djnet
docker run -d --name dj0 --hostname dj0 --network djnet -e ROOT_PASSWORD=secret123 openidentityplatform/opendj:latest
# wait for "OpenDJ is started" in the dj0 log
docker run -d --name dj1 --hostname dj1 --network djnet -e ROOT_PASSWORD=secret123 \
-e MASTER_SERVER=dj0 -e OPENDJ_REPLICATION_TYPE=simple openidentityplatform/opendj:latest
docker logs dj1 | grep ROOT_PASSWORD
# ROOT_PASSWORD=secret123
Expected
No secret reaches the log. The debug dump goes. If the script needs to report what it is doing, it prints only the non-secret values it uses (MASTER_SERVER, MYHOSTNAME, BASE_DN, replication type).
Notes
- The same script also passes the password on the command line of
dsreplication / dsconfig (--bindPassword1 "$ROOT_PASSWORD" etc.), so it is visible in the process list of the container while the tool runs. --bindPasswordFile / --adminPasswordFile avoid that.
- Blocks replication support in a Helm chart (discussion Add an official Helm chart so OpenDJ can be deployed on any Kubernetes cluster #1079): the chart would pass the password from a Secret, and the image would print it right back.
Prior art
Gluu's OpenDJ image (gluufederation/opendj, built on a fork of the same OpenDJ 4 code base) runs the same dsreplication enable / initialize / disable and dsconfig calls. It never puts a password on a command line: it writes the password to a temporary file and passes --bindPasswordFile1/2 and --adminPasswordFile (see /app/scripts/ldap_replicator.py and deregister_peer.py in gluufederation/opendj:4.5.5-1; the image's source repository is no longer public).
Problem
When a container is started with
MASTER_SERVERandOPENDJ_REPLICATION_TYPE,bootstrap/replicate.shprints its whole environment to stdout before it sets up replication (replicate.sh#L23-L24):ROOT_PASSWORDis part of that environment, so the Directory Manager password ends up in the container log. The log is exactly where it should not be:docker logs,kubectl logsand whatever log shipper collects them.Reproduced with
openidentityplatform/opendj:latest(2026-07-17):Expected
No secret reaches the log. The debug dump goes. If the script needs to report what it is doing, it prints only the non-secret values it uses (
MASTER_SERVER,MYHOSTNAME,BASE_DN, replication type).Notes
dsreplication/dsconfig(--bindPassword1 "$ROOT_PASSWORD"etc.), so it is visible in the process list of the container while the tool runs.--bindPasswordFile/--adminPasswordFileavoid that.Prior art
Gluu's OpenDJ image (
gluufederation/opendj, built on a fork of the same OpenDJ 4 code base) runs the samedsreplication enable/initialize/disableanddsconfigcalls. It never puts a password on a command line: it writes the password to a temporary file and passes--bindPasswordFile1/2and--adminPasswordFile(see/app/scripts/ldap_replicator.pyandderegister_peer.pyingluufederation/opendj:4.5.5-1; the image's source repository is no longer public).