Docker, Kubernetes and OpenShift allow mounting secrets as files i.e. instead of having a secret as an environment variable you can specify it as a file in a volume somewhere.
Very useful for setting things like certificates needed for signing things where you may have a bunch of certificates that are supplied by clients.
Is there some way to do this in Aptible or a best practice on how to do something that has the same effect? I was hoping for something like aptible config:set --something <path-to-file> <local file name>
Oh!
We’re very interested in something like this, as well.
We use Hashicorp Vault to store most of our secrets. But the initial login to Vault requires some sort of secret, and there isn’t an ideal way to deliver that secret securely, that I can see. Environment variables are not private enough.
I like @michaelpc 's suggestion of providing a file to mount in the container. I can imagine wanting to mount a small tree of files, perhaps we’d provide a .zip archive. Maybe those files would end up in an /.aptible directory at the root of the container, or something.
Secrets can currently only be exposed to containers as environment variables. It is possible to write the contents of an environment variable to a file, we do this in a number of images used on the platform including the PostgreSQL Database Image, which is the primary way to work around this. An ENTRYPOINT for an application like this would look something like:
#!/bin/sh
# if/else optional depending on your needs
if [ -n "${FILE_VAR_1}" ]; then
echo "${FILE_VAR_1}" > some_file_1.txt
else
echo "FILE_VAR_1 not defined"
exit 1
fi
...
if [ -n "${FILE_VAR_N}" ]; then
echo "${FILE_VAR_N}" > some_file_n.txt
else
echo "FILE_VAR_N not defined"
exit 1
fi
exec "$@"
The content of a local file can be loaded into a variable like so:
The other common way to work around this is to use a service, like @Damon mentioned, such as Hashicorp Vault, AWS Secrets Manager, etc. Then, in the image ENTRYPOINT or as needed, use credentials passed in via the environment to pull secrets.
In situations where you have many secrets, e.g. a certificate per client, storing the data in a service like those mentioned above or integrating management of the secrets into the App and storing them in a Database would probably be more convenient than managing them through the App’s configuration.
For those interested in managing secret files through environment variables, here’s an ENTRYPOINT for that:
#!/bin/sh
set -e
FILE_CONTENT_PREFIX='__FILE__'
FILE_PATH_PREFIX='__FILE_PATH__'
files="$(env | grep -E "^${FILE_PATH_PREFIX}" | sed -E "s/${FILE_PATH_PREFIX}([^=]+)=.*\$/\1/")"
for file in $files; do
content_var="${FILE_CONTENT_PREFIX}${file}"
path_var="${FILE_PATH_PREFIX}${file}"
file_content="$(eval echo "\"\$${content_var}\"")"
file_path="$(eval echo "\"\$${path_var}\"")"
# if/else optional depeding on your needs
if [ -n "$file_content" ]; then
if [ -n "$file_path" ]; then
echo "$file_content" > "$file_path"
else
echo "$path_var is empty"
exit 1
fi
else
echo "$content_var is empty"
exit 1
fi
done
exec "$@"
The content of the file goes in a variable prefixed with __FILE__ and the path of the file to write the content to is prefixed with __FILE_PATH__. For example:
Environment:
__FILE_PATH__FOO=foo.txt
__FILE__FOO="foo bar baz"
__FILE_PATH__BAR=/bar.txt
__FILE__BAR="1\n2\n3"