Skip to content

Instantly share code, notes, and snippets.

@powerman
Last active June 13, 2025 14:31
Show Gist options
  • Save powerman/47f776d933b557ce2557c5d08617218e to your computer and use it in GitHub Desktop.
Save powerman/47f776d933b557ce2557c5d08617218e to your computer and use it in GitHub Desktop.
How to properly support optional secrets.OTHER_TOKEN instead of GitHub default token in GitHub Actions workflows

How to properly support optional secrets.OTHER_TOKEN instead of GitHub default token in GitHub Actions workflows

Caller workflow

✅ DO:

env:
  GITHUB_TOKEN: ${{ secrets.OTHER_TOKEN || github.token }}

jobs:
  job1:
    # ...use env.GITHUB_TOKEN...
  
  reusable:
    uses: org/repo/.github/workflows/reusable.yml@main
    secrets:
      GITHUB_TOKEN: ${{ secrets.OTHER_TOKEN || github.token }}  # duplication because env context is not allowed here

❌ DON'T:

  • Don't use github.token or secrets.GITHUB_TOKEN directly.
  • Don't set env.GITHUB_TOKEN without fallback to github.token.
  • Don't forget to pass token to reusable workflow through secrets.GITHUB_TOKEN (even in case workflow also accept token in some other secrets or inputs).

Reusable workflow

✅ DO:

on:
  workflow_call:    # no token-related inputs/secrets needed

permissions:        # always set minimal required permissions
  contents: read
  issues: write     # example

jobs:
  reusable:
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # for use in steps
    steps:
  
  call_other:
    uses: ./.github/workflows/helper.yml
    secrets:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

❌ DON'T:

  • Don't use github.token.
  • Don't add explicit token inputs/secrets - they add complexity without benefits.
  • Don't skip setting permissions (they will have no effect when using OTHER_TOKEN, but still useful without OTHER_TOKEN).

Using actions

✅ DO:

steps:
  # Use env.GITHUB_TOKEN for maximum compatibility:
  - uses: actions/some-action@v1
    env:
      GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}

  # If action supports token via with:
  - uses: actions/another-action@v1
    env:
      GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}  # always set env too
    with:
      token: ${{ env.GITHUB_TOKEN }}         # and pass via with

❌ DON'T:

  • Don't skip setting env.GITHUB_TOKEN even if action accepts token via with.
  • Don't use github.token or secrets.GITHUB_TOKEN directly.

Explanation

This setup enables:

  1. Alternative token use when needed (secrets.OTHER_TOKEN).
  2. Fallback to default token when not needed.
  3. Proper permissions when using default token.
  4. Maximum compatibility with all action types.

When this fail (on 3rd-party code)

  • If 3rd-party reusable workflow uses github.token (it must use secrets.GITHUB_TOKEN instead).
  • If 3rd-party action uses github.token or secrets.GITHUB_TOKEN (it must use env.GITHUB_TOKEN and/or custom inputs instead - with fallback to any of github.token or secrets.GITHUB_TOKEN).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment