Skip to content

Instantly share code, notes, and snippets.

@simbo1905 simbo1905/README.md
Last active Dec 31, 2018

Embed
What would you like to do?
Use GPG 2.0.22 to decrypt an .env file at start up within an OpenShift s2i image

Use GPG 2.0.22 to decrypt an .env file at start up within an OpenShift s2i image

First, let's generate a strong passphrase to protect the private key. As we are being git driven we do this inside our environment repo:

# ensure that we don't accidentally publish the passphrase to the key
echo passphrase >> .gitignore
git add .gitignore
git commit -m "ignore passphrase"
# generate a random passphrase
base64 < /dev/urandom | head -c 20 > passphrase
# print it out
echo $(<passphrase)

IMPORTANT: You might want to backup this passphrase. If you are using git-secret how to backup passphrase is covered below.

Now generate a key pair for OCD deployment tools using that passphrase using the cli wizard:

gpg --full-generate-key

Now you can export both the public and private key using the email you provided to the wizard:

mkdir gpg
EXPORT_EMAIL=ocd.test@local.host
EXPORT_FINGER=$(gpg --list-secret-key --with-colons $EXPORT_EMAIL | awk -F':' '$1=="fpr"{print $10}' | head -1)
gpg --export-secret-key -a $EXPORT_EMAIL > gpg/$EXPORT_FINGER.prv.key && git add gpg/$EXPORT_FINGER.prv.key
gpg --export -a $EXPORT_EMAIL > gpg/$EXPORT_FINGER.pub.key && git add gpg/$EXPORT_FINGER.pub.key
git commit

The script .s2i/bin/run will try to use an enviroment variable PASSPHRASE to import the secret key and to decrypt the files. You simply need to ensure that the actual passphrase is set as an environment variable on your application.

#!/bin/sh
# this file should be executable at .s2i/bin/run
if [ -z ${PASSPHRASE+x} ]; then
>&2 echo "ERROR no PASSPHRASE"
sleep 1
exit 1
fi
GPG_PRIVATE_KEY=$(find . -type f -name \*.prv.key)
if [[ "$?" -ne "0" ]]; then
>&2 echo "ERROR could not find \*.prv.key"
sleep 1
exit 2
fi
echo $PASSPHRASE | gpg --import --passphrase-fd 0 $GPG_PRIVATE_KEY
if [[ "$?" -ne "0" ]]; then
>&2 echo "ERROR could not decrypt and import $GPG_PRIVATE_KEY"
sleep 1
exit 3
fi
gpg --list-secret-keys
set +x
# gpg decrypt all the *secret files
find ${OCD_CHECKOUT_PATH} -type f -name '*secret' | while read -r SECRET ; do
if [ ! -f "${SECRET%.*}" ]; then
echo $PASSPHRASE | gpg --no-tty --batch --passphrase-fd 0 --output "${SECRET%.*}" --decrypt "${SECRET%.*}.secret"
if [ ! -f "${SECRET%.*}" ]; then
>&2 echo "PANIC! Could not decrypt ${SECRET%.*}.secret. Check 'git secret whoknows' against 'gpg --list-secret-keys'"
sleep 1
exit 4
fi
fi
done
cat $HOME/.env
exec $STI_SCRIPTS_PATH/run
@simbo1905

This comment has been minimized.

Copy link
Owner Author

commented Dec 31, 2018

note that with newer GPG 2.2 you would use the following to import the key:

echo $PASSPHRASE | gpg --pinentry loopback --import --passphrase-fd 0 $GPG_PRIVATE_KEY

and the following to use the key:

echo $PASSPHRASE | gpg --pinentry loopback --passphrase-fd 0 --output "${SECRET%.*}" --decrypt "${SECRET%.*}.secret"

@simbo1905

This comment has been minimized.

Copy link
Owner Author

commented Dec 31, 2018

You can add the passphrase as a kubernetes secret with:

# see https://superuser.com/a/1379872/285325
(passphrase=$(<passphrase); oc create -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: openshift-passphrase
stringData:
  passphrase: ${passphrase}
EOF
)

Then download it into your script rather than set it with an env var using:

PASSPHRASE=$(oc get secrets openshift-passphrase -o yaml | grep passphrase: | awk '{print $2}' | base64 --decode)

That assumes you have oc command working in your image. See https://github.com/ocd-scm/ocd-environment-webhook/blob/0.1.0/bin/oc_wrapper.sh which will refresh a login when it times out. That script needs an account to login to openshift that is allowed to read the secret.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.