safely storing environmental secrets

Introduction

In this post I will cover safely storing environmental variables that are required when using command line tools for digitalocean, AWS, etc. These services all require tokens/passwords that have to be passed and storing them safely is essential. These are my notes on the topic.

Credit to Graham Watts

The approach I have adopted here follows Grahm Watts' wonderful post Managing Secrets In Linux . His blog post is much more detailed than my notes here and his blog looks like a great DevOps resouce in general. That said, any mistakes presented here are my own. Follow along with caution.

secret-tools

The central tool in the approach I will use to store and access tokens for services like digitalocean is secret-tool. On Pop!_OS / Ubuntu this is not installed by default and requires libsecret-tools to be installed:

$ sudo apt install libsecret-tools

A simple verification of the installation can be had by executing secret-tool

$ secret-tool
usage: secret-tool store --label='label' attribute value ...
secret-tool lookup attribute value ...
secret-tool clear attribute value ...
secret-tool search [--all] [--unlock] attribute value ...
secret-tool lock --collection='collection'

An example: digitalocean and terraform

Let's start with a motivating example, using terraform to create digitalocean assets. A command that we would need to run would be something like:

$ terraform plan \
-var "do_token=${DO_PAT}" \
-var "pvt_key=$HOME/.ssh/do_test"

In the above, the digitalocean personal access token DO_PAT, stored as an environmental variable, and a private ssh key do_test are passed to terraform.

Environmental variables

How do we store the envirnomental variable DO_PAT? In order to create an environmental variable we could type

$ export DO_PAT = asdlkjhadakfaklsdjfb(fake)

However, this only persists with the current shell and will disappear when we exit.

How NOT to do it!!!

As Graham Watts says in the motivating post, cited above, a bad way to have persistent storage of the environmemtal variable would be to add the export command to your .bashrc:

.bashrc

#... contents of .bashrc above ...

export DO_PAT = asdlkjhadakfaklsdjfb(fake)

This loads the variable with each new shell. However, this approach stores the token in plain text and many people have this file under (public) version control, making it a very poor approach.

A better way, with gnome-keyring

With secret-tool available it is simple to store the token, or other secret, in the gnome-keyring. In this example, we can do:

$ secret-tool store --label="DO_PAT" token digitalocean
Password: asdlkjhadakfaklsdjfb(fake)

To be clear, the token is entered when the Password: prompt appears. In order to recall the the token use:

$ secret-tool lookup token digitalocean
asdlkjhadakfaklsdjfb(fake)

With this structure in place secret-tool lookup can be:

  1. called directly (no storage as an environment variable)
    $ terraform plan \
    -var "do_token=$(secret-tool lookup token digitalocean)" \
    -var "pvt_key=$HOME/.ssh/do_test"
  2. or, used to export the variable in .bashrc

    .bashrc

    #... contents of .bashrc above ...

    export DO_PAT = $(secret-tool lookup token digitalocean)

The first option, calling secret-tool directly, is safer because the token is never available as an environment variable. However, there are a variety of reasons why the environmental variable approach might be needed or preferred. So, I include the second option here.

That's all folks!

That's all for my notes. Again, be sure to check out the original post for a more detailed discussion of this all: Managing Secrets In Linux .