---
title: "How to recover a GitHub Actions secret"
date: 2023-11-02
tags:
  - github
  - actions
  - secrets
  - tailscale
basename: ../../notes/recover-github-action-secret
---

Sometimes you fuck up and lose your only copy of a GitHub secret that you can't replace easily, such as a [Cachix](https://www.cachix.org/) signing key. However you lucked out and that key is actually saved in GitHub Actions secrets...which won't let you read the contents of that secret for understandable security reasons. Here's how you work around that.

First, make sure [Deno](https://deno.land) is installed and copy this program to `recover-secret.ts`.

```ts
const port = 8080;

const handler = async (req: Request): Promise<Response> => {
  const body = await req.text();
  console.log(body);

  return new Response();
};

console.log(`HTTP server running. Access it at: http://localhost:${port}/`);
Deno.serve({ port }, handler);
```

Run it with `deno run -A recover-secret.ts`.

Next go to the [Tailscale admin console OAuth clients section](https://login.tailscale.com/admin/settings/oauth) and generate a new OAuth client that lets you create auth keys (you want the write on devices scope). Add a helpful description like "GitHub Actions secret recovery" and copy the client ID and secret to your password manager. Then add them as GitHub secrets named `TAILSCALE_CLIENT_ID` and `TAILSCALE_CLIENT_SECRET`.

Now create a new GitHub Actions workflow with the following contents:

```yaml
on:
  workflow_dispatch:

jobs:
  recoversecret:
    runs-on: ubuntu-latest
    steps:
      - name: Tailscale
        uses: tailscale/github-action@v2
        with:
          oauth-client-id: ${{ secrets.TAILSCALE_CLIENT_ID }}
          oauth-secret: ${{ secrets.TAILSCALE_CLIENT_SECRET }}
          tags: tag:ci
          version: 1.52.0
      - name: "Recover secret"
        run: |
          echo ${SECRET} > ./output.txt
          curl --data-binary @./output.txt ${TARGET}
        env:
          SECRET: ${{ secrets.CACHIX_SIGNING_KEY }}
          TARGET: "http://kaine.shark-harmonic.ts.net:8080"
```

Replace the contents of `TARGET` as facts and circumstances demand.

Now you can recover your secret by hitting the "Run workflow" button on the Actions tab of your repo. The secret will be in your terminal, and you can copy it to your password manager as a note.
