joho / godotenv

A Go port of Ruby's dotenv library (Loads environment variables from .env files)
http://godoc.org/github.com/joho/godotenv
MIT License
8.5k stars 406 forks source link

Add "-s" option to delete dotenv files on command failure #140

Open vmarkovtsev opened 3 years ago

vmarkovtsev commented 3 years ago

Rationale: sometimes we want to secure our environment variables so that the next command cannot access them. We can chain the two operations:

godotenv cmd
rm .env

The problem here is if the command fails, we do not remove the file.

We can code some shell:

godotenv cmd || rm cmd && exit 1

There are two problems now:

  1. We lose the original exit code.
  2. We have to write this for each executed command.

godotenv -s solves everything.

joho commented 3 years ago

I'm sorry, call it a failure of imagination on my part, but what specifically is the use-case here?

The scope of this library is to provide developer convenience when implementing apps the "12 factor" way (for all the later uncovered sins of that approach) and I don't see how this fits within the intended purpose.

vmarkovtsev commented 3 years ago

Sure. Let me note that this PR changes the CLI code only, as I predicted that changing the library for my specific use case would be too much.

As you may have heard, codecov had a security incident and their bash uploader was compromised. Many had the following GHA config:

env:
    MY_SECRET: ${{ secrets.MY_SECRET }}

my_job:
  - name: some shell
    run: |
      commandAWantsSecret ...
      commandBWantsSecret ...
      commandCWantsSecret ...
  - name: codecov
    uses: codecov/codecov-action@v1

and their MY_SECRET was recorded and hijacked by codecov. To overcome the threat in the future with another third-party GHA or used tool in that GHA, we started to write this:

my_job:
  - name: some shell
    run: |
      MY_SECRET=${{ secrets.MY_SECRET }} commandAWantsSecret ...
      MY_SECRET=${{ secrets.MY_SECRET }} commandBWantsSecret ...
      MY_SECRET=${{ secrets.MY_SECRET }} commandCWantsSecret ...

and this works. However, if there are tens of secrets, this quickly gets notorious. I did some googling and found some statically linked binaries to convert .env files to environment variables for the specified command and found godotenv. Thanks to my patch, it becomes possible to setup the environment only once:

my_job:
  - name: some shell
    run: |
      echo 'MY_SECRET=${{ secrets.MY_SECRET }}' >.env
      godotenv commandAWantsSecret ...
      godotenv commandBWantsSecret ...
      godotenv commandCWantsSecret ...
      rm .env

I hit two problems though:

The first problem can be worked around by intimidating shell scripting, the second is not solvable at all. Hence the PR.