Storing secrets in plain text is a bad idea (OWASP). Let’s explore a method for storing secrets in an encrypted file using GnuPG.

Set up your GPG key

Run gpg --list-keys to see if you have any existing keys. If you don’t have any GPG keys, you will need to create one.

gpg --full-generate-key

Encrypt the secret(s)

First, store the secrets in a temporary file.

touch /tmp/secrets.txt
# /tmp/secrets.txt
export SECRET_TOKEN_A="░░░░░░░░░░░░░░░░░░░░░░░"
export SECRET_TOKEN_B="░░░░░░░░░░░░░░░░░░░░░░░"

Then, encrypt /tmp/secrets.txt and remove it.

gpg --encrypt --armor --recipient [email protected] /tmp/secrets.txt
rm /tmp/secrets.txt

Move the encrypted secrets to your project directory and rename the file to .envrc.asc.

mv /tmp/secrets.txt.asc /home/your/project/.envrc.asc

Direnv

Install and set up direnv.

Configure direnv to use your encrypted secrets.

touch /home/your/project/.envrc
#!/usr/bin/env bash
# .envrc contents
# Decrypt and source secrets
if [ -f .envrc.asc ]; then
eval "$(gpg --quiet --decrypt .envrc.asc)"
fi
# Other variables
export OTHER_ENV_VAR="foo"

Reload direnv.

direnv reload

Store AWS credentials with GPG

A similar technique can be used to configure AWS CLI using the credential_process setting

Create a temporary file for storing your AWS credentials.

touch /tmp/aws-secrets.json

Edit /tmp/aws-secrets.json

{
"Version": 1,
"AccessKeyId": "░░░░░░░░░░░░░░░░░░░░░░░",
"SecretAccessKey": "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░",
"SessionToken": null,
"Expiration": null
}

Encrypt /tmp/aws-secrets.json; then remove it.

gpg --encrypt --armor --recipient [email protected] /tmp/aws-secrets.json
rm /tmp/aws-secrets.json

Move aws-secrets.json.asc to your ~/.aws

mv /tmp/aws-secrets.json.asc ~/.aws

Edit a new or existing profile in ~/.aws/config.

[profile example]
region = us-east-1
credential_process = gpg --quiet --decrypt aws-secrets.json.asc

Test your AWS CLI configuration.

aws --profile=example sts get-caller-identity

You should see something like

{
"UserId": "░░░░░░░░░░░░░░░░░░░░░░░",
"Account": "░░░░░░░░░░░░░░░░░░░░░░░",
"Arn": "arn:aws:iam::░░░░░░░░░░░░░░░░░░░░░░░:░░░░░░░/░░░░░░░░░░░"
}

Never check your encrypted secrets into source control

Encrypted secrets are still valuable to attackers due to harvest now, decrypt later. They should never be shared.