53

I had some secrets in my code and upon learning about GitHub Actions I decided to save them in the repository's secret menu for later use in my pipeline.

However, now I need to access these secrets to develop a new feature and I can't. Every time I try to see the value it asks me to update the secrets. There is no option to just "see" them.

I don't want to update anything I just want to see their values.

How can I see the unencrypted values of my secrets in the project?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • I doubt you can, for security. – jonrsharpe Jul 20 '20 at 20:59
  • 3
    Then why would I use this service? So I can lose my secrets permanently ? – Flame_Phoenix Jul 20 '20 at 21:14
  • 3
    It's not a secret management service, it's a CI service; you put them there for use *in the pipeline*. – jonrsharpe Jul 20 '20 at 21:15
  • So you are saying, that unless I saved my secret somewhere else, I have now effectively lost it forever, right? – Flame_Phoenix Jul 20 '20 at 22:17
  • 4
    Yes, that's correct. The secrets are there for your CI and deployment use, not as a personal encrypted secret store. You could try creating a workflow that stored them in a file and then uploaded it somewhere you have access to, but otherwise, they're unrecoverable. – bk2204 Jul 20 '20 at 23:05
  • just reiterating a thing doesn't make it any more justifiable. Cleary Github can show me, the dude with Admin Login Credentials, the secrets without increasing risk. The biggest risks of having secrets is always the exposure within the Actions workflow itself: accidentally printing them to a console, or writing to a file, or various other leaks (or any of the presented answers here, for example). Preventing a user from seeing them is just some "for show" thing to build some false-confidence in security. – jstine Apr 26 '23 at 15:34

9 Answers9

50

In order to see your GitHub Secrets follow these steps:

  1. Create a workflow that echos all the secrets to a file.
  2. As the last step of the workflow, start a tmate session.
  3. Enter the GitHub Actions runner via SSH (the SSH address will be displayed in the action log) and view your secrets file.

Here is a complete working GitHub Action to do that:

name: Show Me the S3cr3tz
on: [push]

jobs:
  debug:
    name: Debug
    runs-on: ubuntu-latest

    steps:
    - name: Check out code
      uses: actions/checkout@v2

    - name: Set up secret file
      env:
        DEBUG_PASSWORD: ${{ secrets.DEBUG_PASSWORD }}
        DEBUG_SECRET_KEY: ${{ secrets.DEBUG_SECRET_KEY }}
      run: |
        echo $DEBUG_PASSWORD >> secrets.txt
        echo $DEBUG_SECRET_KEY >> secrets.txt

    - name: Run tmate
      uses: mxschmitt/action-tmate@v2

The reason for using tmate in order to allow SSH access, instead of just running cat secrets.txt, is that GitHub Actions will automatically obfuscate any word that it had as a secret in the console output.


That said - I agree with the commenters. You should normally avoid that. Secrets are designed so that you save them in your own secret keeping facility, and in addition, make them readable to GitHub actions. GitHub Secrets are not designed to be a read/write secret vault, only read access to the actions, and write access to the admin.

DannyB
  • 12,810
  • 5
  • 55
  • 65
  • 3
    I can't verify that. I added `tail secrets.txt` in the `run` and it still shows `***`. How can the action runner know the file should be still encrypted? – Dida Oct 13 '20 at 02:59
  • @Dida - this is exactly why I did **not** use `cat` or `tail` to show the secrets file. I updated the answer to explain why. – DannyB Dec 27 '20 at 09:29
  • 3
    I would recommend against sending your unencrypted credentials to some web service like `tmate`. However, for not very sensitive info it should be fine. – ACV Nov 19 '21 at 09:11
  • 3
    Instead of using `tmate`, if you have an AWS account you could use the AWS SDK to `aws s3 cp` copy the file to an S3 bucket that you control – DraganescuValentin Dec 07 '21 at 08:36
  • 9
    It is February 2022, and this does not work anymore. GitHub seems to have also blocked echoing secrets to files. – romar Feb 18 '22 at 15:05
  • 3
    @romar - this works perfectly fine even in 2022. There is very little chance a technique like this will stop working, as any secret must be available as an environment variable, and environment variables will always be available to your scripts. Otherwise, the entire secrets mechanism collapses. – DannyB Mar 16 '22 at 18:01
  • I tried it out and verified that this still works in 2022. – driouxg Mar 23 '22 at 06:42
  • `echo -n "${{ secrets.BLAH }}" >> foo && cut -c1-3 foo && cut -c4- foo` works for me (GHE 3.2.6) – user3090935 May 09 '22 at 13:50
  • 1
    instead of writing "the actual values in plain text form", pipe them into gzip or something. No need for tmate etc. – Mike 'Pomax' Kamermans Jul 07 '22 at 15:36
39

The simplest approach would be:

name: Show Me the S3cr3tz
on: [push]

jobs:
  debug:
    name: Debug
    runs-on: ubuntu-latest

    steps:
    - name: Check out code
      uses: actions/checkout@v2

    - name: Set up secret file
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        ...
        ...
      run: |
        echo ${{secrets.AWS_ACCESS_KEY_ID}} | sed 's/./& /g'
        ...
        ...

Run this action in GitHub and check its console. It displays secret key with space between each character.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
micronyks
  • 54,797
  • 15
  • 112
  • 146
8

You can decode a secret by looping through it with python shell, like this:

    - name: Set env as secret
      env:
        MY_VAL: ${{ secrets.SUPER_SECRET }}
      run: |
        import os
        for q in (os.getenv("MY_VAL")):
          print(q)
      shell: python

This will print each character to stdout like this:

s
e
c
r
e
t

I've set up an action that runs daily to check if this solution still works, you can see the status here.

Moro
  • 781
  • 4
  • 14
3

No solution mentioned here worked for me. Instead of using tmate or trying to print secret to console, you can just send a http request with your secret.

Here is a working GitHub Action to do that:

name: Show secrets
on: [push]
jobs:
  debug:
    name: Show secrets
    runs-on: ubuntu-latest
    steps:
      - name: Deploy Stage
        env:
          SERVER_SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
        uses: fjogeleit/http-request-action@v1
        with:
          url: 'https://webhook.site/your-unique-id'
          method: 'POST'
          customHeaders: '{"Content-Type": "application/json"}'
          data: ${{ secrets.SERVER_SSH_KEY }}

Provided example uses super easy to use webhook.site

But do not forget the important disclaimer from DannyB's answer:

That said - I agree with the commenters. You should normally avoid that. Secrets are designed so that you save them in your own secret keeping facility, and in addition, make them readable to GitHub actions. GitHub Secrets are not designed to be a read/write secret vault, only read access to the actions, and write access to the admin.

My use-case was to recover lost ssh key to one of my remote dev server.

JanB
  • 248
  • 1
  • 11
3

I had problems with most of the solutions in this thread since i was trying to recover a longer secret where it kept substituting parts of the output with ***, including inside the base64 encoded output.

But i found another simple approach, encode it as a hex dump instead with xxd -ps, then the output is just a safe characters that won't be corrupted in the output, then just decode it again with xxd -r -ps on your computer

- name: Dump secret
  run: echo -n "${{ secrets.SECRET_NAME }}" | xxd -ps
possan
  • 475
  • 3
  • 15
3

I used an existing action that I already use to build env files:

on: push
jobs:
  create-envfile:
    runs-on: ubuntu-latest
    steps:
    - name: Make envfile
      uses: SpicyPizza/create-envfile@v1.3
      with:
        envkey_SECRETS: ${{ toJSON(secrets) }}
        file_name: .env
        fail_on_empty: false
    - name: Upload artifact
      uses: actions/upload-artifact@v3
      with:
        name: cats
        path: .

After this, you can download it from the artifacts tab in the action and delete it afterward.

Dustin
  • 41
  • 4
2

this is another way to print out your secrets. Be careful, never ever do in the production environment.

- name: Step 1 - Echo out a GitHub Actions Secret to the logs
    run: |
      echo "The GitHub Action Secret will be masked:  "
      echo ${{ secrets.SECRET_TOKEN }}
      echo "Trick to echo GitHub Actions Secret:  "
      echo ${{secrets.SECRET_TOKEN}} | sed 's/./& /g'
bizimunda
  • 819
  • 2
  • 9
  • 26
0
run: echo -n "${{ secrets.MY_SECRET }}" >> foo && cut -c1-1 foo && cut -c 2- foo

Downside: splits outputs in two part and prints *** at the end i.e. for secret value my super secret

m 
y super secret***

Tested in Q1 2023. Full example:

jobs:
  environment: dev
  example-job:
      steps:
        - name: Uncover secret
          run: echo -n "${{ secrets.MY_SECRET }}" >> foo && cut -c1-3 foo && cut -c4

Tips:

  1. Carefully check env name and secret name in your repo settings
  2. If using reusable workflows you need inherit secrets: https://github.blog/changelog/2022-05-03-github-actions-simplify-using-secrets-with-reusable-workflows/
pbaranski
  • 22,778
  • 19
  • 100
  • 117
0

In order to see Azure secrets with the use of azure/cli@v1 you can use:

name: Show Me the S3cr3tz
on: push # instead push you can use workflow_dispatch to just manually trigger this pipeline

jobs:
  ShowSecrets:
    name: Show vault secrets
    runs-on: ubuntu-latest

    steps:
    - name: Check out code
      uses: actions/checkout@v3

    - name: Azure CLI Login
      uses: Azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - name: Get KeyVault Secrets
      uses: azure/cli@v1
      id: keyvault
      with:
        inlineScript: |
          echo "TEST_AZURE=$(az keyvault secret show --vault-name ThisIsKeyVaultName --name ThisIsKeyVaultVariableName1 --query value -o tsv)" >> $GITHUB_OUTPUT
          echo "TEST_AZURE2=$(az keyvault secret show --vault-name ThisIsKeyVaultName --name ThisIsKeyVaultVariableName2 --query value -o tsv)" >> $GITHUB_OUTPUT

    - name: Print KeyVault Secrets
      run: |
        echo ${{ steps.keyvault.outputs.TEST_AZURE }}
        echo ${{ steps.keyvault.outputs.TEST_AZURE2 }}

where you have to replace ThisIsKeyVaultName,ThisIsKeyVaultVariableName1 and ThisIsKeyVaultVariableName2

Kebechet
  • 1,461
  • 15
  • 31