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.