GitHub Token Operations¶
Guide to GitHub token creation and management for cluster services.
Quick Reference¶
| Property | Value |
|---|---|
| Actions Runner Token Path | secret/fzymgc-house/cluster/github |
| Token Key | windmill_actions_runner_token |
| Runner Namespace | actions-runner-system |
| Runner Label | windmill-sync |
Token Types¶
| Type | Use Case | Expiry | Security |
|---|---|---|---|
| Fine-grained PAT | Service automation | Configurable | Higher (recommended) |
| Classic PAT | Legacy integrations | Configurable | Lower |
| GitHub App | Org-level automation | No expiry | Highest |
Required Tokens¶
Actions Runner Controller¶
Repository access for self-hosted runners.
- Scope:
repo,workflow - Stored:
secret/fzymgc-house/cluster/github
ArgoCD¶
Repository access for GitOps sync.
- Scope: Repository read
- Stored:
secret/fzymgc-house/cluster/argocd
HCP Terraform¶
VCS integration for speculative plans.
- Type: GitHub App
- Configuration: HCP Terraform settings
Token Creation¶
Option 1: Personal Access Token (Classic)¶
- Navigate to GitHub Settings
- Go to https://github.com/settings/tokens
-
Or: GitHub > Settings > Developer settings > Personal access tokens > Tokens (classic)
-
Generate New Token
- Click "Generate new token" > "Generate new token (classic)"
- Note: Give it a descriptive name like
actions-runner-controller-selfhosted-cluster -
Expiration: Recommended: 90 days (you'll need to rotate it)
-
Select Scopes
For repository-level runners, select these scopes:
repo(Full control of private repositories)workflow(Update GitHub Action workflows)
Important: These are the ONLY two scopes needed.
- Generate and Copy Token
- Click "Generate token" at the bottom
- IMPORTANT: Copy the token immediately - you won't see it again
- Token format:
ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Option 2: Fine-Grained Personal Access Token (Recommended)¶
- Navigate to Fine-Grained Tokens
- Go to https://github.com/settings/personal-access-tokens/new
-
Or: GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens
-
Configure Token
- Token name:
actions-runner-controller-selfhosted - Expiration: 90 days (recommended)
- Description: Self-hosted GitHub Actions runner
-
Resource owner:
fzymgc-house -
Repository Access
- Select: Only select repositories
-
Choose:
fzymgc-house/selfhosted-cluster -
Permissions
Under "Repository permissions": - Actions: Read and write - Contents: Read-only - Metadata: Read-only (automatically selected) - Workflows: Read and write
- Generate and Copy Token
- Click "Generate token"
- Copy the token:
github_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Store Token in Vault¶
# Make sure you're authenticated to Vault
vault token lookup
# Store the token
vault kv put secret/fzymgc-house/cluster/github \
windmill_actions_runner_token="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Verify it was stored
vault kv get secret/fzymgc-house/cluster/github
# Get the actual token value (if needed for debugging)
vault kv get -field=windmill_actions_runner_token secret/fzymgc-house/cluster/github
Token Rotation¶
Since tokens expire, you'll need to rotate them periodically:
- Generate a new token following the same steps
- Update Vault:
vault kv patch secret/fzymgc-house/cluster/github \ windmill_actions_runner_token="<new-token>" - ExternalSecret will automatically sync the new token
- Runner pods will automatically use the new token
Verify Runner Deployment¶
After storing the token:
# Check if ExternalSecret synced the token
kubectl --context fzymgc-house get externalsecret github-token -n actions-runner-system
kubectl --context fzymgc-house get secret github-token -n actions-runner-system
# Check controller deployment
kubectl --context fzymgc-house get pods -n actions-runner-system
# Verify runner registered with GitHub
kubectl --context fzymgc-house get runnerdeployment -n actions-runner-system
kubectl --context fzymgc-house describe runnerdeployment windmill-sync-runner -n actions-runner-system
Verify on GitHub¶
Check that the runner appears in GitHub:
- Go to: https://github.com/fzymgc-house/selfhosted-cluster/settings/actions/runners
- You should see a runner listed with label:
windmill-sync - Status should show as "Idle" (green)
Troubleshooting¶
Token Not Working¶
# Check controller logs
kubectl --context fzymgc-house logs -n actions-runner-system \
-l app.kubernetes.io/name=actions-runner-controller --tail=100
# Common errors:
# - "401 Unauthorized": Token invalid or expired
# - "403 Forbidden": Insufficient permissions
# - "404 Not Found": Repository access not granted
Runner Not Appearing in GitHub¶
- Check token scopes: Must have
repoandworkflow(classic) or equivalent fine-grained permissions - Verify repository access: Token must have access to
fzymgc-house/selfhosted-cluster - Check controller status:
kubectl get pods -n actions-runner-system - Review logs: Look for authentication errors in controller logs
ExternalSecret Not Syncing¶
# Check ExternalSecret status
kubectl --context fzymgc-house describe externalsecret github-token -n actions-runner-system
# Common issues:
# - Vault path wrong: Should be secret/fzymgc-house/cluster/github
# - Vault key wrong: Should be windmill_actions_runner_token
# - ClusterSecretStore not configured: Check 'vault' ClusterSecretStore exists
Token Comparison¶
| Feature | Classic PAT | Fine-Grained PAT |
|---|---|---|
| Scope | All repos user has access to | Specific repositories only |
| Permissions | Broad (repo, workflow) |
Granular (Actions, Workflows, etc.) |
| Expiration | Custom (max 1 year) | Custom (max 1 year) |
| Security | Lower | Higher (recommended) |
| Setup | Simpler | More complex |
Recommendation: Use Fine-Grained PAT for better security.
Security Best Practices¶
- Token Storage: Never commit tokens to Git. Always use Vault.
- Token Scope: Use minimum required scopes. Fine-grained tokens are more secure.
- Token Expiration: Set reasonable expiration (90 days recommended).
- Token Rotation: Have a process to rotate before expiration.
- Access Control: Limit who can access the Vault secret.
- Rotate immediately if compromised
See Also¶
- Vault Operations - Secret storage
- GitHub PAT Documentation
- Actions Runner Controller