GitHub Provider¶
The GitHub provider enables SecretZero to store and manage secrets in GitHub Actions. It supports token authentication for managing repository secrets and environment-specific secrets.
Overview¶
The GitHub provider is ideal for:
- CI/CD pipelines using GitHub Actions workflows
- Repository automation requiring secure credential management
- Multi-repository deployments needing consistent secrets across repos
- Environment-specific deployments (production, staging, development)
- Teams using GitHub Enterprise with custom API endpoints
Supported Target Types¶
| Target Type | Description | Use Case |
|---|---|---|
github_secret |
GitHub Actions secret (repository or environment) | Workflow credentials, API keys, deployment tokens, environment-specific secrets |
Authentication¶
Token Authentication¶
The GitHub provider uses Personal Access Tokens (PAT) or GitHub Apps for authentication.
When to use: All scenarios with GitHub Actions secret management.
Creating a Personal Access Token¶
- Navigate to GitHub Settings:
-
Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
-
Generate new token (classic):
- Click "Generate new token (classic)"
- Give it a descriptive name (e.g., "SecretZero Token")
-
Set expiration (recommended: 90 days with rotation)
-
Select scopes:
repo- Full control of private repositories (required for repository secrets)-
workflow- Update GitHub Action workflows (optional, for workflow management) -
Generate and save token:
- Click "Generate token"
- Copy the token immediately (it won't be shown again)
-
Store securely or export as environment variable
-
Set environment variable:
GitHub Enterprise Support¶
For GitHub Enterprise Server, specify a custom API URL:
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
api_url: https://github.mycompany.com/api/v3
Configuration¶
Basic Configuration¶
version: '1.0'
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
- name: api_key
kind: random_string
config:
length: 32
charset: alphanumeric
targets:
- provider: github
kind: github_secret
config:
owner: myorganization
repo: myrepo
Multi-Repository Configuration¶
Deploy secrets to multiple repositories:
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
- name: shared_api_key
kind: random_string
config:
length: 32
targets:
# Backend repository
- provider: github
kind: github_secret
config:
owner: myorg
repo: backend-service
# Frontend repository
- provider: github
kind: github_secret
config:
owner: myorg
repo: frontend-app
# Mobile repository
- provider: github
kind: github_secret
config:
owner: myorg
repo: mobile-app
Environment-Specific Configuration¶
Use environment secrets for production, staging, and development:
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
- name: database_password
kind: random_password
config:
length: 32
special: true
targets:
# Production environment
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: production
# Staging environment
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: staging
# Development environment (repository-level)
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
Target Types¶
GitHub Secret¶
The github_secret target type stores secrets in GitHub Actions. It supports both repository-level and environment-specific secrets based on configuration.
Configuration Options¶
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
owner |
string | Yes | - | Repository owner (user or organization) |
repo |
string | Yes | - | Repository name |
environment |
string | No | - | Environment name for environment-specific secrets |
secret_name |
string | No | secret name | Custom secret name (defaults to secret name in uppercase) |
Example: Repository Secret¶
secrets:
- name: api_key
kind: random_string
config:
length: 32
charset: alphanumeric
targets:
- provider: github
kind: github_secret
config:
owner: myorganization
repo: myrepo
The secret will be available in workflows as ${{ secrets.API_KEY }}.
Example: Custom Secret Name¶
secrets:
- name: database_password
kind: random_password
config:
length: 32
special: true
exclude_characters: '"@/\`'
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
secret_name: DB_PASSWORD_PROD
The secret will be available as ${{ secrets.DB_PASSWORD_PROD }}.
Example: Environment Secret¶
Environment secrets are created by adding an environment parameter:
secrets:
- name: database_url
kind: static
config:
default: postgresql://prod-db.example.com:5432/myapp
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: production
Example: Multi-Environment Secrets¶
Deploy the same secret to multiple environments:
secrets:
- name: api_endpoint
kind: static
config:
default: https://api.example.com
targets:
# Production
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: production
secret_name: API_ENDPOINT
# Staging
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: staging
secret_name: API_ENDPOINT
Complete Examples¶
Example 1: Simple Application Secrets¶
version: '1.0'
variables:
github_org: myorganization
github_repo: myapp
environment: production
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
# API Key
- name: api_key
kind: random_string
config:
length: 32
charset: alphanumeric
targets:
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
# Database Password
- name: database_password
kind: random_password
rotation_period: 90d
config:
length: 32
special: true
exclude_characters: '"@/\`'
targets:
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
environment: "{{var.environment}}"
# JWT Signing Secret
- name: jwt_secret
kind: random_string
config:
length: 64
charset: alphanumeric
targets:
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
metadata:
project: "{{var.github_repo}}"
owner: backend-team
Example 2: Multi-Environment Setup¶
version: '1.0'
variables:
github_org: myorganization
github_repo: myapp
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
# Database credentials for all environments
- name: database_password
kind: random_password
config:
length: 32
special: true
exclude_characters: '"@/\'
targets:
# Production environment
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
environment: production
# Staging environment
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
environment: staging
# Development (repository-level)
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
# API endpoints (static values)
- name: api_url
kind: static
config:
default: https://api.example.com
targets:
# Production endpoint
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
environment: production
secret_name: API_URL
- name: api_url_staging
kind: static
config:
default: https://staging-api.example.com
targets:
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: "{{var.github_repo}}"
environment: staging
secret_name: API_URL
Example 3: Multi-Repository Deployment¶
version: '1.0'
variables:
github_org: myorganization
providers:
github:
kind: github
auth:
kind: token
config:
token: ${GITHUB_TOKEN}
secrets:
# Shared API key across services
- name: external_api_key
kind: random_string
config:
length: 32
charset: alphanumeric
targets:
# Backend service
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: backend-service
environment: production
# Frontend app
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: frontend-app
environment: production
# Worker service
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: worker-service
environment: production
# Service-specific secrets
- name: database_password
kind: random_password
config:
length: 32
special: true
targets:
# Only backend needs database access
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: backend-service
environment: production
# Worker also needs database
- provider: github
kind: github_secret
config:
owner: "{{var.github_org}}"
repo: worker-service
environment: production
PAT Permissions and Scopes¶
Required Token Scopes¶
For Repository Secrets¶
repo- Full control of private repositories- Grants access to create, update, and delete repository secrets
- Required for both public and private repositories
For Environment Secrets¶
repo- Full control of private repositories- Environment secrets require repository admin access
- Same permissions as repository secrets
Token Best Practices¶
- Use fine-grained tokens when available:
- Limit token scope to specific repositories
- Set shorter expiration periods
-
Revoke tokens after use in CI/CD
-
Rotate tokens regularly:
-
Use different tokens for different purposes:
- Separate tokens for production and non-production
- Different tokens per team or project
-
Dedicated tokens for automation
-
Audit token usage:
- Review token activity in GitHub Settings
- Monitor API rate limits
- Track secret updates through lockfile
Integration with GitHub Actions Workflows¶
Using Secrets in Workflows¶
Once synced, secrets are available in your GitHub Actions workflows:
Repository Secret Usage¶
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy with secrets
run: |
echo "API_KEY=${{ secrets.API_KEY }}" >> .env
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
./deploy.sh
env:
JWT_SECRET: ${{ secrets.JWT_SECRET }}
Environment Secret Usage¶
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy-prod:
runs-on: ubuntu-latest
environment: production # Must specify environment
steps:
- uses: actions/checkout@v3
- name: Deploy to production
run: |
echo "Deploying to production..."
./deploy.sh
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
Environment Protection Rules¶
Combine environment secrets with protection rules:
# .github/workflows/deploy.yml
name: Deploy with Approval
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to staging
run: ./deploy.sh staging
env:
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production # Requires manual approval
steps:
- name: Deploy to production
run: ./deploy.sh production
env:
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
Configure environment protection rules in GitHub: 1. Repository Settings → Environments → production 2. Required reviewers: Select team members 3. Wait timer: Optional deployment delay 4. Deployment branches: Limit to specific branches
Best Practices¶
1. Use Environment Secrets for Production¶
# Good: Environment-specific secrets with protection
secrets:
- name: prod_db_password
kind: random_password
config:
length: 32
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
environment: production # Enables environment protection
# Avoid: Repository-level secrets for production
secrets:
- name: prod_db_password
kind: random_password
config:
length: 32
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp # No environment protection
2. Rotate Tokens Regularly¶
secrets:
- name: api_key
kind: random_string
rotation_period: 90d # Automatic rotation
config:
length: 32
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: myapp
3. Use the Lockfile¶
# Generate lockfile on first sync
secretzero sync -f Secretfile.yml
# Commit lockfile to track secret lifecycle
git add .secretzero.lock
git commit -m "Update secret lockfile"
# Verify lockfile before syncing
secretzero sync -f Secretfile.yml --verify-lock
4. Implement Naming Conventions¶
# Good: Clear, consistent naming
secrets:
- name: database_password # Becomes DATABASE_PASSWORD
- name: api_external_key # Becomes API_EXTERNAL_KEY
- name: jwt_signing_secret # Becomes JWT_SIGNING_SECRET
# Avoid: Ambiguous names
secrets:
- name: secret1
- name: key
- name: password
5. Deploy to Multiple Repositories Consistently¶
When you need the same secret in multiple repositories, deploy it consistently:
# Good: Deploy same secret to multiple repositories
secrets:
- name: shared_api_key
kind: random_string
config:
length: 32
targets:
- provider: github
kind: github_secret
config:
owner: myorg
repo: backend-service
- provider: github
kind: github_secret
config:
owner: myorg
repo: frontend-app
- provider: github
kind: github_secret
config:
owner: myorg
repo: worker-service
# Track with lockfile to ensure consistency
6. Audit Secret Access¶
# Use GitHub audit log to track secret access
# Organization Settings → Audit log → Filter by "secret"
# Monitor secret updates with lockfile
git log .secretzero.lock
# Review workflow runs that use secrets
# Actions → Select workflow → Review runs
7. Never Commit Tokens¶
# Add to .gitignore
echo "GITHUB_TOKEN" >> .gitignore
echo ".env" >> .gitignore
echo "*.secret" >> .gitignore
# Remove committed token
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch .env' --prune-empty --tag-name-filter cat -- --all
Troubleshooting¶
Authentication Failed¶
Error: GitHub authentication failed. Check credentials and configuration.
Solutions:
-
Verify token is set:
-
Test token with GitHub CLI:
-
Check token hasn't expired:
- Go to GitHub Settings → Developer settings → Personal access tokens
-
Verify token expiration date
-
Verify token scopes:
-
For GitHub Enterprise, verify API URL:
Permission Denied¶
Error: Resource not accessible by integration or 403 Forbidden
Solutions:
-
For repository secrets, ensure token has
reposcope: -
For environment secrets, ensure repository admin access:
- Environment secrets require admin access to the repository
-
Check repository Settings → Manage access
-
Test permissions:
Secret Not Appearing in Workflows¶
Error: Secret is synced but not available in workflows
Solutions:
-
Verify secret name (case-sensitive):
-
For environment secrets, ensure workflow specifies environment:
-
Check secret in GitHub UI:
- Repository Settings → Secrets and variables → Actions
-
Verify secret exists and name matches
-
Workflow permissions:
Rate Limits¶
Error: API rate limit exceeded or 403 rate_limit_exceeded
Solutions:
-
Check current rate limit:
-
Authenticated requests have higher limits:
- Unauthenticated: 60 requests/hour
- Authenticated: 5,000 requests/hour
-
GitHub Enterprise: Often higher limits
-
Implement backoff strategy:
-
Deploy to multiple repositories efficiently:
-
Cache SecretZero operations:
Secret Encryption Failed¶
Error: Failed to encrypt secret or Public key not found
Solutions:
- SecretZero automatically handles encryption, but if issues occur:
- Verify repository exists and is accessible
-
Check repository settings allow Actions
-
Test repository access:
-
Ensure Actions is enabled:
- Repository Settings → Actions → General
- Actions permissions: Allow all actions
Environment Not Found¶
Error: Environment does not exist
Solutions:
- Create environment first:
- Repository Settings → Environments → New environment
-
Enter environment name (e.g., "production")
-
Environment names are case-sensitive:
-
Create environments via GitHub CLI:
-
Verify environment exists:
GitHub Enterprise Support¶
Configuration¶
providers:
github_enterprise:
kind: github
auth:
kind: token
config:
token: ${GITHUB_ENTERPRISE_TOKEN}
api_url: https://github.mycompany.com/api/v3
secrets:
- name: api_key
kind: random_string
config:
length: 32
targets:
- provider: github_enterprise
kind: github_secret
config:
owner: myorg
repo: myrepo
API URL Format¶
- GitHub Cloud:
https://api.github.com(default) - GitHub Enterprise Server:
https://github.mycompany.com/api/v3 - GitHub AE:
https://github.ae/api/v3
Testing Enterprise Connection¶
# Test API connectivity
curl -H "Authorization: token $GITHUB_ENTERPRISE_TOKEN" \
https://github.mycompany.com/api/v3/user
# Test with SecretZero
secretzero test -f Secretfile.yml
Enterprise-Specific Considerations¶
- SSL Certificates:
- Ensure valid SSL certificate
-
For self-signed certificates, configure trust
-
Network Access:
- Verify network connectivity to enterprise server
-
Check firewall rules and proxy settings
-
API Version:
- Use
/api/v3endpoint for GitHub Enterprise Server -
Verify API version compatibility
-
Rate Limits:
- Enterprise may have different rate limits
- Contact GitHub Enterprise admin for limits
Cost and Limits¶
GitHub Actions Usage¶
- Public repositories: Unlimited Actions minutes
- Private repositories: Free tier includes minutes (varies by plan)
- Secrets: No additional cost, included in GitHub plan
Limits¶
- Repository secrets: Up to 100 secrets per repository
- Environment secrets: Up to 100 secrets per environment
- Secret size: Maximum 64 KB per secret
- Secret name: Maximum 512 characters
Best Practices for Limits¶
- Combine multiple values in JSON secrets when appropriate
- Use environment variables for non-sensitive configuration
- Implement secret cleanup for unused secrets
- Plan secret naming conventions to stay within limits