Handling Secrets
Passing secrets, like passwords, safely to the server, especially in containers, can be tricky. For example, the settings:
-Darcadedb.server.rootPassword=password
for the root password, or:
-Darcadedb.server.defaultDatabases=database[username:password]
for database and user generation are comfortable,
but present the issue that passwords passed this way are readable in plaint text
in applications like htop or docker compose top.
This is the case because these settings are passed ultimately via command-line to the JVM (even if using JAVA_OPTS or ARCADEDB_SETTINGS).
In the following, an approach is presented to avoid this problem.
The idea is to use the special environment variable JAVA_TOOL_OPTIONS to pass the settings
directly into the JVM (alternatively JDK_JAVA_OPTIONS or the undocumented _JAVA_OPTIONS may be used).
However, just using this particular environment variable would mean that the
JVM writes the contents of this variable to the standard error stream,
which means the secrets would appear in logs.
For the root password this can be avoided using the setting:
-Darcadedb.server.rootPasswordPath=/path/to/root_secret
which passes the secret via a plain text file which is mounted to a known path inside the container. This is a common practice to pass secrets to containers, for example with Docker compose.
To suppress this logging for non-root secrets,
a workaround can be used
by providing the secret also file-based and wrapping the server.sh script:
#!/bin/sh
export JAVA_TOOL_OPTIONS="-Darcadedb.server.defaultDatabases=database1[user1:`cat /path/to/user_secret`]"
./bin/server.sh 2> >(grep -v "^Picked up JAVA_TOOL_OPTIONS:") &
PID="$!"
unset JAVA_TOOL_OPTIONS
wait $PID
This way the secrets are passed directly into the JVM without being resolved before,
and the stderr logging is filtered.
The server is send to the background and its process ID saved.
Then, by unsetting the JAVA_TOOL_OPTIONS variable immediately after using it,
ensures the secrets will not linger in the environment.