plugins/patterns/skills/jwt-authentication/SKILL.md
Generate JWTs for GitHub App authentication. Direct JWT generation for app-level operations, installation discovery, and bootstrapping workflows.
npx skillsauth add adaptive-enforcement-lab/claude-skills jwt-authenticationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
JWTs authenticate your GitHub App itself, not a specific installation. They enable:
JWT Limitations
- Cannot access repository contents
- Cannot create issues, pull requests, or commits
- 10-minute expiration (maximum allowed)
- App-level permissions only
See examples.md for detailed code examples.
The GitHub CLI handles JWT generation automatically when using GitHub App credentials.
jobs:
list-installations:
runs-on: ubuntu-latest
steps:
- name: List app installations
env:
GH_APP_ID: ${{ secrets.CORE_APP_ID }}
GH_APP_PRIVATE_KEY: ${{ secrets.CORE_APP_PRIVATE_KEY }}
run: |
# gh CLI generates JWT automatically
gh api /app/installations \
--jq '.[] | {id: .id, account: .account.login}'
How it works:
GH_APP_ID + GH_APP_PRIVATE_KEY triggers automatic JWT generationFor custom implementations or languages without GitHub CLI support.
jobs:
manual-jwt:
runs-on: ubuntu-latest
steps:
- name: Generate JWT manually
id: jwt
env:
APP_ID: ${{ secrets.CORE_APP_ID }}
PRIVATE_KEY: ${{ secrets.CORE_APP_PRIVATE_KEY }}
run: |
# Install JWT tool
npm install -g jsonwebtoken
# Create JWT generation script
cat > generate-jwt.js << 'EOF'
const jwt = require('jsonwebtoken');
const fs = require('fs');
const appId = process.env.APP_ID;
const privateKey = process.env.PRIVATE_KEY;
const now = Math.floor(Date.now() / 1000);
const payload = {
iat: now - 60, // Issued 60 seconds in past
exp: now + (10 * 60), // Expires in 10 minutes
iss: appId
};
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });
console.log(token);
EOF
# Generate JWT
JWT_TOKEN=$(node generate-jwt.js)
echo "::add-mask::$JWT_TOKEN"
echo "token=$JWT_TOKEN" >> $GITHUB_OUTPUT
- name: Use JWT
env:
GITHUB_TOKEN: ${{ steps.jwt.outputs.token }}
run: |
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/app
Security: Mask JWT Token
Always use
echo "::add-mask::$JWT_TOKEN"to prevent token exposure in logs.
For Python-based workflows and automation.
jobs:
python-jwt:
runs-on: ubuntu-latest
steps:
- name: Generate JWT with Python
id: jwt
env:
APP_ID: ${{ secrets.CORE_APP_ID }}
PRIVATE_KEY: ${{ secrets.CORE_APP_PRIVATE_KEY }}
run: |
pip install PyJWT cryptography
python << 'EOF'
import jwt
import time
import os
app_id = os.environ['APP_ID']
private_key = os.environ['PRIVATE_KEY']
now = int(time.time())
payload = {
'iat': now - 60,
'exp': now + (10 * 60),
'iss': app_id
}
token = jwt.encode(payload, private_key, algorithm='RS256')
# Mask token in logs
print(f"::add-mask::{token}")
# Output token
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write(f"token={token}\n")
EOF
- name: Use JWT
env:
GITHUB_TOKEN: ${{ steps.jwt.outputs.token }}
run: |
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/app/installations
See reference.md for additional techniques and detailed examples.
See examples.md for detailed code examples.
See examples.md for code examples.
See reference.md for complete documentation.
documentation
Workload Identity Federation implementation guide. GKE setup, IAM bindings, ServiceAccount configuration, migration from service account keys, and troubleshooting patterns.
development
Secure GitHub Actions trigger patterns for pull requests, forks, and reusable workflows. Preventing privilege escalation and code injection through trigger misconfiguration.
development
Structured framework for evaluating GitHub Actions security before adoption. Trust tiers, risk assessment checklist, and decision tree for action evaluation.
testing
Securely store GitHub App credentials across different environments. GitHub Actions secrets, external CI, Kubernetes, and automated rotation patterns.