DEV Community

Cover image for Stop using the environment variables for sensitive keys in Rails
Ramesh Naidu Allu
Ramesh Naidu Allu

Posted on

Stop using the environment variables for sensitive keys in Rails

When it comes to secure storage of API keys or tokens in the application development, we got used to environment variables for a long time. Of course, I was comfortable too with env vars until I found about the security lapse of using those. This article shows the drawbacks of using environment variables and it’s alternative in Rails to mitigate these issues.

Let's recap the method of using the env vars:

To use the environment variables config, we have options like creating a .bashrc or .zshrc or .env files to store the sensitive key information. The variables are stored as key-value pairs in the plain text as mentioned below.

SOME_API_TOKEN = 'vfsdjkgb4irhgoreidfnvldaknvd9wej09qwfnsl'
SCERET_KEY = 'fe8934ygt983qhv8934hf934q8gf343qhjrajvlksdvklvdsnl'</span>
Enter fullscreen mode Exit fullscreen mode

and the value can be accessed thru ENV['SOME_API_TOKEN']. Look at the below example.

ENV['SOME_API_TOKEN']
=>'vfsdjkgb4irhgoreidfnvldaknvd9wej09qwfnsl'</span>
Enter fullscreen mode Exit fullscreen mode

Even though we are not committing .env file to version control, there is a security risk involved with environment variables. The major risks are:

  • Exposure of sensitive information like keys and API tokens through log reports during debugging and error logging.
  • This stolen keys can be misused by other people which may increase your server costs to sky-high.

Some other disadvantages:

  • deployment is challenging due to dealing with many environment variables
  • chances of accidental pushing to version control

Let’s see the solution for those concerns:

Now the question comes what we need to use instead of environment variables.

The answer is Rails credentials.

In the previous versions, its called Rails secrets. Since version 5.2, it got more stable and it’s much better now with the feature of generating separate credential files for each environment in Rails 6.0.

Features of Rails credentials:

  • Rails credentials are encrypted. They can’t be decrypted without a master key. So you can push the credentials file to version control and track changes.
  • No hustle of managing the different environment variables in deployment. The only environment variable required in production is the master key (i.e. RAILS_MASTER_KEY)
  • Rails scaffolding will add the master.key file in .gitignore. So, there is no scope of accidental moving to version control.
  • Easy to deal with environments for different environment variables. Separate files will be created for each environment from the Rails version 6.0 onwards.

Now, Let’s see how it works:

1. The Rails new application scaffold will create a credentials.yml.enc and master.key files in the config folder. The file credentials.yml.enc is encrypted and the contents of this encrypted file will look like as below.

***config/credentials.yml.enc*** 
 cbV3dZL3BQ50HnYPq4xT7wcsSMjQC6H876w/0c8/lm0LPeqgvwwTfmX40PjBub3KOgTsSW7WtSUHF3RtwEogSdb//ewRXQsDbwShjFVvHw2DWu+1ckCuyPWMXcxLaAjvZZro/haciyv9aEM+XcvMVQa8HucicttjZ+s6Q1Ojstn8B4KkIP1yLRKUqntP7bM9Q4M7424UQBS/CGgaSlFFFWboFSBZ4pDxgQq/eWgiz84dLGkVmqfc5O1F+qUin74n1iC1TxI0sBBEnIWJgdqOlel1EGZMm4tNQAoB9kMv5txV39HfIPoXseaow0DyGI7ne2wn4Jt3FDEikikK2pP2mbDtVCJDCAmzeFcKHUotMppbitx/SwG0sy4lyurslmtlGpulWdd2UU7254JmPAT7G0ToN6E99hkMbbmv--xjeqEcsQl6TyNszD--iRVSGKRyloGXGO8glue9nQ==</span>
Enter fullscreen mode Exit fullscreen mode

2. The above file is an encrypted version of our secret keys and passwords. The data can be opened only with the master key. Rails will add this master.key to .gitignore automagically.

3. Since it is encrypted, we cant edit the file directly. We need the following command to add or modify the keys in the credentials.

EDITOR="code --wait" bin/rails credentials:edit</span>
Enter fullscreen mode Exit fullscreen mode
  • Here we need to mention the type of editor you want to use. Since I’m using VScode editor, using the term code.
  • For example, If you want to open in atom editor, you should mention EDITOR = "atom --wait" and the rest of the command follows.
  • It’s important to pass a wait flag. Otherwise, the credentials will be saved immediately with no chance to edit.

4. After running the above command, the decrypted credentials file will open in the editor. The credentials are stored in the YAML format as shown below.

This is the default credentials.yml.enc file, with only one key active.

# aws: 
#   access_key_id: 123 
#   secret_access_key: 345</span> <span id="c3d4" class="dz kk iy fq kb b dj lb lc ld le lf km s kn"># Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.</span> <span id="ec37" class="dz kk iy fq kb b dj lb lc ld le lf km s kn">secret_key_base:68ef73fa111800521c3a62237a7398a5e49c684bc6f50092ab98b742d151f6f8ef45cc337e5a7dedd6145624ddf5345cdf262653ef403a8018852a411ce04cf</span>
Enter fullscreen mode Exit fullscreen mode

5. Now we can add or edit the keys as per our requirement. Let us say, we want to add some credentials of AWS. See the below example.

aws:
  api_token: 'vfsdjkgb4irhgoreidfnvldaknvd9wej09qwfnsl'
  access_key: 'fe8934ygt983qhv8934hf934q8gf343qhjrajvlksdvklvdsnl'</span> <span id="3648" class="dz kk iy fq kb b dj lb lc ld le lf km s kn"># Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.</span> <span id="74bf" class="dz kk iy fq kb b dj lb lc ld le lf km s kn">secret_key_base:068ef73fa111800521c3a62237a7398a5e49c684bc6f50092ab98b742d151f6f8ef45cc337e5a7dedd6145624ddf5345cdf262653ef403a8018852a411ce04cf</span>
Enter fullscreen mode Exit fullscreen mode

That’s it. After save and exiting the editor, you can see the message **File encrypted and saved** in the terminal.

6. To access these credentials, you need the following code.

Rails.application.credentials.aws[:api_token]
=> "vfsdjkgb4irhgoreidfnvldaknvd9wej09qwfnsl"</span>
Enter fullscreen mode Exit fullscreen mode

7. Coming to production, we need to create only one environment variable in production. i.e. RAILS_MASTER_KEY = <your-master-key> Rails will use this environment variable as master.key for encryption and decryption. Thus, it enables accessing the rails credentials in the production environment.

8. You can also set the separate keys for each environment with the following command.

EDITOR="code --wait" bin/rails credentials:edit --environment development</span>
Enter fullscreen mode Exit fullscreen mode

This command will create the file development.yml.enc and the new encryption key development.key in the folder config/credentials. The remaining process of accessing and modifying the credentials are the same as above.

Conclusion:

The security of sensitive keys in application development is an important aspect. The use of environment variables is getting deprecated due to security lapses. Hope this article gave enough information to start working with the Rails credentials. There are also third-party gems which are addressing these issues. If you are using any other way to handle this sensitive data, please let me know by commenting below.

Top comments (0)