This guide explains how to create and configure a GitHub Personal Access Token for jgn.dev to access your posts repository and avoid API rate limiting.
Without authentication, GitHub limits API requests to 60 per hour. With a Personal Access Token, you get 5,000 requests per hour, which is essential for:
- Fetching posts from your GitHub repository
- Avoiding rate limiting during development
- Enabling webhook functionality for automatic updates
- Accessing private repositories (if needed)
- Log in to GitHub and click your profile picture in the top-right corner
- Select "Settings" from the dropdown menu
- Scroll down to "Developer settings" in the left sidebar
- Click "Personal access tokens"
- Choose "Tokens (classic)" for compatibility
- Click "Generate new token" → "Generate new token (classic)"
- Enter a descriptive note like
jgn.dev blog application - Set expiration (recommended: 90 days or longer for production)
- Select the required scopes (see permissions section below)
Select only the minimal permissions needed:
- ✅
public_repo- Access public repositories- This allows reading your public posts repository
- ✅
repo- Full control of private repositories- Only needed if your posts repository is private
- ❌
workflow- Not needed - ❌
write:packages- Not needed - ❌
delete:packages- Not needed - ❌
admin:repo_hook- Not needed (webhooks are configured separately)
- Click "Generate token" at the bottom
- Copy the token immediately - GitHub will only show it once
- Store it securely - treat it like a password
Set the token as an environment variable:
macOS/Linux:
export GITHUB_TOKEN=ghp_your_token_here
# Add to your shell profile for persistence
echo 'export GITHUB_TOKEN=ghp_your_token_here' >> ~/.zshrc
source ~/.zshrcWindows (PowerShell):
$env:GITHUB_TOKEN="ghp_your_token_here"
# For persistence, add to your PowerShell profile
Add-Content $PROFILE '$env:GITHUB_TOKEN="ghp_your_token_here"'The deployment scripts will automatically use the GITHUB_TOKEN environment variable:
export GITHUB_TOKEN=ghp_your_token_here
./scripts/deploy-gcp-cloud-run.sh- Use descriptive names when creating tokens
- Set reasonable expiration dates (30-90 days for development, longer for production)
- Use minimal required permissions only
- Store tokens as environment variables, never in code
- Regenerate tokens periodically
- Delete unused tokens immediately
- Never commit tokens to Git repositories
- Don't share tokens in chat, email, or documentation
- Avoid setting "No expiration" unless absolutely necessary
- Don't grant excessive permissions (like admin access)
Error: 401 Unauthorized - Bad credentials
Solutions:
- Verify token is correctly set:
echo $GITHUB_TOKEN - Check token hasn't expired in GitHub Settings
- Ensure token has correct permissions (public_repo or repo)
- Try regenerating the token if it's corrupted
Error: 403 Forbidden - API rate limit exceeded
Solutions:
- Confirm token is being used: Check application logs
- Verify environment variable is set:
echo $GITHUB_TOKEN - Check token permissions include repository access
- Wait for rate limit reset (resets every hour)
Error: 403 Forbidden - Repository access blocked
Solutions:
- For private repos: Ensure token has
reposcope - For public repos: Ensure token has
public_reposcope - Verify repository exists and is accessible
- Check organization permissions if applicable
Warning: GITHUB_TOKEN environment variable is not set
Solutions:
- Set the environment variable:
export GITHUB_TOKEN=ghp_your_token_here - Restart your terminal to load new environment variables
- Check your shell profile (.zshrc, .bashrc, etc.) for persistence
Verify your token works with a simple curl command:
curl -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/userExpected response: Your GitHub user information in JSON format.
Run the jgn.dev application and check logs for:
✅ Successfully authenticated with GitHub API
✅ Rate limit: 5000 requests per hour
- Go to GitHub Settings → Developer settings → Personal access tokens
- Review active tokens and their last usage
- Delete unused tokens regularly
- Click on the token name in your token list
- Click "Regenerate token"
- Update the environment variable with the new token
- Restart your application
When your token expires:
- Create a new token following the same steps
- Update your environment variables
- Update production deployments with the new token
- Delete the expired token from GitHub
Your GitHub token needs access to the repository containing your blog posts:
- Repository must be accessible with your token permissions
- Posts should be in Markdown format with YAML frontmatter
- Repository structure should match your site configuration
your-posts-repo/
├── post-1.md
├── post-2.md
├── drafts/
│ └── upcoming-post.md
└── README.md
The application automatically detects and uses your GitHub token:
token := os.Getenv("GITHUB_TOKEN")
if token != "" {
// Use authenticated requests (5,000/hour limit)
} else {
// Use unauthenticated requests (60/hour limit)
}Monitor your usage in the application logs:
INFO: GitHub API rate limit: 4,832/5,000 remaining
INFO: Rate limit resets at: 2024-01-15T10:30:00Z
Blog Development:
- Repository access:
public_repoorrepo - Typical usage: 50-200 API calls per session
- Recommended expiration: 90 days
Production Deployment:
- Repository access:
public_repoorrepo - Typical usage: 10-50 API calls per day
- Recommended expiration: 1 year (with monitoring)
If you encounter issues:
- Check the troubleshooting section above
- Review GitHub's status page for API issues
- Open an issue in the jgn.dev repository with error logs
- Include relevant error messages but never include your actual token