GitHub Token Handling - lukeocodes/wikiinator GitHub Wiki
The Problem We Solved
When creating this GitHub Action, we encountered several token-related issues that are common when building composite actions that need authentication.
Key Lessons Learned
1. Composite Actions Cannot Use Expressions as Defaults
What doesn't work:
inputs:
github-token:
description: "GitHub token"
required: true
default: ${{ github.token }} # ❌ This fails silently!
Why it fails:
- Composite actions don't support expressions in the
default
field - The token becomes
undefined
or empty - No error is thrown - it just silently fails
The solution:
inputs:
github-token:
description: "GitHub token"
required: false # Make it optional
# In the action step:
env:
INPUT_GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
2. Different Token References
We learned the distinction between different token references:
${{ secrets.GITHUB_TOKEN }}
- Traditional way, still works${{ github.token }}
- Modern way, equivalent functionality- Both have the same permissions and capabilities
3. Smart Fallback Pattern
The best pattern we discovered:
# action.yml
inputs:
github-token:
description: "GitHub token. Optional - defaults to github.token"
required: false
runs:
using: "composite"
steps:
- name: Run action
shell: bash
run: ${{ github.action_path }}/script.sh
env:
INPUT_GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
Benefits:
- Users don't need to explicitly pass a token
- Still allows custom tokens if needed
- Backward compatible
- Clear documentation about optionality
4. Token Validation
Always validate the token is available:
if [ -z "$INPUT_GITHUB_TOKEN" ]; then
echo "::error::GitHub token is required"
exit 1
fi
5. Token Debugging (Security-Safe)
Show token info without exposing it:
# Show first 8 characters and length for debugging
echo "Token info: ${INPUT_GITHUB_TOKEN:0:8}... (${#INPUT_GITHUB_TOKEN} chars)"
Implementation Example
Our final implementation:
- Optional input with clear description
- Logical OR fallback in environment variable
- Early validation in script
- Debug-friendly logging without security risks
This pattern makes the action both user-friendly (no token required in most cases) and flexible (custom token supported when needed).