Can your repository secrets be logged with Github Actions? A guide on trying not to get sued and/or fired!
While migrating travis CI to github actions, I wanted to test whether/when the secrets on a repository get logged.
§ Set some secrets
I created an empty repository and set up some secrets (Settings > Secrets > New repository secret):
- NEVER_SEE_TOKEN, with value "SEENO EVIL".
- ECHOED_TOKEN, with value "echoed":
§ Good usage: the command succeeds
My very first attempt was running a command using the secret properly. Here, it is expected that github will hide the secret variables.
name: secret
on:
push:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check successful action with secret is not logged and works
run: echo ${{ secrets.NEVER_SEE_TOKEN }} | grep "SEENO"
Let's check the log!
> Check successful action with secret is not logged and works
Run echo *** | grep "SEENO"
echo *** | grep "SEENO"
shell: /bin/bash -e {0}
***
Fantastic, exactly how it should be.
§ Strange usage: echoing the secrets
Let's add another step, echoing the secret to STDOUT.
- name: Echoed secrets are not logged!
run: echo ${{ secrets.ECHOED_TOKEN }}
Log:
> Echoed secrets are not logged!
Run echo ***
echo ***
shell: /bin/bash -e {0}
***
In this case, github actions saves us from doomsday but we are really flexing our madness here. Nonetheless, if you really want the secret to be printed (maybe for debugging) you may use the workaround posted here:
- name: This is going to be printed!
run: echo ${{secrets.SECRET_TOKEN}} | sed 's/./& /g'
§ Still good usage: the command fails but syntax is fine
If one job failed, the secrets should not be printed, right?
test-bad:
runs-on: ubuntu-latest
steps:
- name: Check unsuccessful action with secret is not logged and works
run: echo ${{ secrets.NEVER_SEE_TOKEN }} | grep "GOOD"
Log:
> Check unsuccessful action with secret is not logged and works
Run echo *** | grep "GOOD"
echo *** | grep "GOOD"
shell: /bin/bash -e {0}
Error: Process completed with exit code 1.
Right!
§ Bad usage: the command fails because of wrong syntax
This is when you get fired. If a command is called using the wrong syntax (or your secret refers to what should be a file but it isn't, like in this case) the error trace of the command might reveal the secrets, letting them exposed to the whole Internet.
tests-bad-syntax:
runs-on: ubuntu-latest
steps:
- name: Check unsuccessful action with secret is logged and fails
run: grep "JULY" ${{ secrets.NEVER_SEE_TOKEN }}
Log:
> Check unsuccessful action with secret is logged and fails
Run grep "JULY" ***
grep "JULY" ***
shell: /bin/bash -e {0}
grep: SEENO: No such file or directory
grep: EVIL: No such file or directory
§§ How to fix this situation
At least the first time using an action of this kind, we could redirect the
STERR to /dev/null. Thus, the possible stack of errors will be removed
from the logs.
tests-bad-syntax-recovered:
runs-on: ubuntu-latest
steps:
- name: Check unsuccessful action with wrong syntax and secret is not logged
run: grep "JULY" ${{ secrets.NEVER_SEE_TOKEN }} 2> /dev/null
Log:
> Check unsuccessful action with wrong syntax and secret is not logged
Run grep "JULY" *** 2> /dev/null
grep "JULY" *** 2> /dev/null
shell: /bin/bash -e {0}
Error: Process completed with exit code 2.
Yay! Another way would be to maybe try the commands locally. Just maybe.