Github actions makes it easy to run ci/cd, but working with secrets is a mess. You can write them, but you can’t read them. You cannot echo them, GitHub obfuscates them. Sure, it’s for security, but you can workaround that security if you must.

I am forgetful and I would really like to see sometimes what I wrote in those GitHub secrets, without me having to ssh into the runner.

I am using firebase for a couple of my apps, so google cloud secret manager felt like the right fit. This post shows how to pull secrets from Google Cloud Secret Manager into GitHub actions, and use those secrets in place of GitHub secrets.

Prepare for Access

To read secret manager values from GitHub actions, you need to give a permission to do so.

Go to service accounts, add a new service account. Click to create. In permissions, choose Secret Manager Secret Accessor.

google cloud secret manager read-only service account
google cloud secret manager read-only service account

Go to keys, create a new key and save the json file.

Go to Github secrets and add a GOOGLE_APPLICATION_CREDENTIALS_JSON, paste the contents of the json file and save. Add also GCP_PROJECT_ID and paste your project id (found in the URL, project query param).

Prepare Workflow

To read google cloud secrets, you need to point GitHub to which project (GCP_PROJECT_ID) and which access (GOOGLE_APPLICATION_CREDENTIALS_JSON).

Part of the workflow could look like this:

name: Deploy Expo App to TestFlight

on:
  push:

jobs:
  check_versioning:
    runs-on: macos-latest
    env:
      GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
    steps:
      - uses: actions/checkout@v4
      - name: Auth gcloud SDK
        uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_JSON }}
      - name: Install gcloud SDK
        uses: google-github-actions/setup-gcloud@v2
        with:
          project_id: ${{ secrets.GCP_PROJECT_ID }}
      - name: Read secrets into environment
        run: |
          echo "Fetching secrets from Google Secret Manager"
          APPSTORE_API_KEY_PATH=$(gcloud secrets versions access latest --secret=APPSTORE_API_KEY_PATH)
          APPSTORE_API_KEY_ID=$(gcloud secrets versions access latest --secret=APPSTORE_API_KEY_ID)
          gcloud secrets versions access latest --secret=APPSTORE_API_PRIVATE_KEY > $APPSTORE_API_KEY_PATH
          APPSTORE_ISSUER_ID=$(gcloud secrets versions access latest --secret=APPSTORE_ISSUER_ID)
          
          
          echo "::add-mask::$APPSTORE_API_KEY_ID"
          echo "::add-mask::$APPSTORE_ISSUER_ID"
          echo "::add-mask::$APPSTORE_API_KEY_PATH"
          
          # Export for later steps
          echo "APPSTORE_API_KEY_ID=$APPSTORE_API_KEY_ID" >> $GITHUB_ENV
          echo "APPSTORE_ISSUER_ID=$APPSTORE_ISSUER_ID" >> $GITHUB_ENV
          echo "APPSTORE_API_KEY_PATH=$APPSTORE_API_KEY_PATH" >> $GITHUB_ENV
    

In my example, I saved the appstore credentials in the secret manager.

I first need to authenticate with gcloud api, which will call the secret manager service. I need to provide it with my service account key and the project id.

The part "Read secrets into environment" will:

  • fetch the secrets from cloud secret manager
  • mask the secrets, so they don't leak in logs
  • export the secrets to GITHUB_ENV, so they are immediately available to next steps in the job

Secrets won't be available to other jobs, just to all the steps in the current job.

Youtube: https://youtu.be/acw3gXZFTlA