Last active
April 12, 2024 12:24
-
-
Save bamarch/931af0bb1914e886cd91dab0df6e5ccd to your computer and use it in GitHub Desktop.
Entrypoint: swap envs for secrets (POSIX)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# What: | |
# A POSIX compliant entrypoint script that replaces environment variable values with the content of files | |
# e.g. secrets mounted into the container using the Kubernetes Secrets Store CSI Driver | |
# Why: | |
# - You run applications in Kubernetes and use the Kubernetes Secrets Store CSI Driver. | |
# - A POSIX compatible container requires secrets to be passed in as environment variables | |
# - You cannot modify the application | |
# - You can modify the container ENTRYPOINT | |
# - A lightweight solution is preferred (no need for a sidecar or mutating webhook) | |
# How: | |
# 1) In "containers" "env" objects in use the following format: | |
# MY_ENV_VAR=">>secretfile:$secretStoreVolumeMountPath/$mySecretName" | |
# e.g. | |
# DB_PASSWORD=">>secretfile:/mnt/secret-store/database-password" | |
# | |
# where $secretStoreVolumeMountPath is the mountPath of the secret store volume, | |
# and $mySecretName is the name of the secret as per SecretProviderClass, and | |
# together they form the path to the secret file in the container's filesystem. | |
# | |
# 2) In the container's ENTRYPOINT, use the shell form and source this script (named swap-env-secrets.sh in the example) | |
# ENTRYPOINT ["sh", "-c", "source swap-env-secrets.sh && <my executable> <arg1> <arg2>"] | |
# e.g. | |
# ENTRYPOINT ["sh", "-c", "source swap-env-secrets.sh && dotnet my/path/to.dll"] | |
#======================================================================================================================= | |
# Alternatives: | |
# * Kubernetes Secrets and valueFrom.secretKeyRef | |
# - increases exposure of the secret values | |
# - if secrets are themselves created by CSI (e.g. using secretObjects from SecretProviderClass) this method has | |
# 0 to 1 issues, which impacts CronJobs | |
# * Hashicorp Vault using Banzai Cloud mutating webhook | |
# - similar schema for substiuting env values (which inspired this script - see https://bank-vaults.dev/docs/mutating-webhook/) | |
# - uses a mutating webhook instead of a POSIX script, does not require ENTRYPOINT changes | |
# - requires additional infrastructure (Vault, Banzai Cloud, etc.) | |
#======================================================================================================================= | |
set -e # exit if there are errors during this script | |
# Loop over environment variables (they're fed in at the loop closure) | |
while IFS='=' read -r key value; do | |
# Check for values starting with ">>secretfile:" | |
if [ "${value#>>secretfile:}" != "$value" ]; then | |
# Get the file path by removing the prefix ">>secretfile:" | |
secretfile="${value#>>secretfile:}" | |
# Check if the file exists | |
if [ -e "$secretfile" ]; then | |
# If file exists, replace the value of the env var with the secret from the file | |
secretvalue=$(cat "$secretfile") | |
export "$key=$secretvalue" | |
else | |
# If file does not exist, exit with error | |
echo "ERROR: file '$secretfile' does not exist" | |
exit 1 | |
fi | |
fi | |
# This is a POSIX way of ensuring variables modified within the while loop are remembered | |
done <<EOT | |
$(printenv) | |
EOT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment