dotenv-vault: No dependency .env encrypt tool
Tags: bash, opensource, productivity, cli
Published: 2018-06-15 16:30:07

---
title: dotenv-vault: No dependency .env encrypt tool
published: true
description: 
tags: bash, oss, productivity, cli
---

# tl;dr

dotenv-vault is a simple dotenv management tool, keeping tokens secret.

{% github https://github.com/acro5piano/dotenv-vault %}

# Why

How do you manage `.env` file in your repository?

The file may contain some secret tokens. In OSS, those information must not open. Even in private repository, we shouldn't include secret information into Git repository, because a lot of stakeholder including out-source developers will commit the code.

However, secret information is needed in applications so we may want to include them to the repository.

According to this article, major option is to use KMS, Key Management Service. Major cloud service such as AWS and GCP provide the service.

https://www.reddit.com/r/devops/comments/52pl5c/how_do_you_manage_env_dotenv_files/

However, I would like to manage them more simple way without any plugins and dependencies.

# Options

yaml_vault is a good tool to keep YAML files secret.

{% github https://github.com/joker1007/yaml_vault %}

It is written in Ruby. Ruby on Rails use YAML file for configurations. So the tool is popular with Ruby on Rails applications.

Rails 5.2 has the similar function by default. If we run the following command, the file is decrypted and our editor will run. The file encrypted again after editing the file.

```bash
bin/rails credentials:edit
```

However, my project does not use neither Ruby on Rails nor YAML. Just `.env` and `.env.local`, `.env.production` files exists.

So I created [dotenv-vault](https://github.com/acro5piano/dotenv-vault) (apparently inspired by yaml_vault).


# Philosophy

- Less dependency. This is convenient if we run in CI.
- Simple. Easy setup and no DSL, zero learning cost.
- Productive. Automate as possible.

Less dependency is really important because we could use this tool in any environments, any projects, with zero cost. Currently dotenv-vault depends on the three:

- Bash
- Openssl
- Perl

I chose Perl to parse dotenv file because Perl does not change command syntax between operating systems. `sed` differs between BSD and GNU.
Major OS, such as macOS and Ubuntu, have Perl by default.

# How to use

## Manually

After install (check out the repo), add `# encrypt-me` comment at the end of line to be encrypted:

```bash
# .env

APP_ENV=production
APP_KEY=super_secret_value # encrypt-me
```

Then run the following command:

```bash
$ dotenv-vault encrypt .env
```

You may be asked the password to encrypt, input it and press return:

```bash
Please input password and press Return:
```

It will output encrypted file as standard output like this:

```bash
APP_ENV=production
APP_KEY=U2FsdGVkX19VF+rLm7ypGQFl76Sq7QUEaU5uM+AlQmRxcKMTTj63R81K4U0WYZzy # decrypt-me
```

So you can redirect the output to a file:

```bash
$ dotenv-vault encrypt .env > .env.production
```

To decrypt the file, run:

```bash
$ dotenv-vault decrypt .env.production
```

Then input the password and decrypted output will be shown.

## In CI

In CI, we cannot input the password manually, so set `DOTENV_PASSWORD` environment variable in your CI service.

```bash
$ env DOTENV_PASSWORD=foo dotenv-vault decrypt .env.production > .env
```

(Actually `env DOTENV_PASSWORD=foo` is not needed)

## Add tokens

It is not convenient if we should decrypt & encrypt every time we add new token.

`dotenv-vault generate` simply generate encrypted token.


```bash
$ dotenv-vault generate 'FIREBASE_TOKEN=new_secret_token'
```

The command output will be like this:

```bash
FIREBASE_TOKEN=U2FsdGVkX19NWIIPCamKJOFdJktBSETdFNV6BIwBlkjBNhCRQ18z2zDtVRu3fO79 # decrypt-me
```

So we can redirect the output to add new token.

```bash
$ dotenv-vault generate 'FIREBASE_TOKEN=new_secret_token' >> .env.production
```

# Thanks

I use Bashtub to run unit test for bash script. Bashtub is really simple and good tool.

{% github https://github.com/ueokande/bashtub %}

# Conclusion

In my use case, dotenv-vault provides useful features. If you have any opinions, please let me know!

Thanks.