type: runbook
status: active
timestamp: 2026-07-02
tags: [security, pat, github, ci, deploy, dispatch]
status: active
timestamp: 2026-07-02
tags: [security, pat, github, ci, deploy, dispatch]
WORKSPACE_DISPATCH_PAT setup
Create fine-grained PAT for downstream repos to trigger umbrella deploy via repository_dispatch.
WORKSPACE_DISPATCH_PAT setup
Fine-grained PAT. Only chirag127/workspace. Only contents:write + metadata:read. Downstream repos use it to fire repository_dispatch at umbrella after CI green.
Why fine-grained not classic
Classic PAT = full account scope. Leak = full account compromise. Fine-grained = single-repo blast radius.
Create the PAT
- Open https://github.com/settings/personal-access-tokens/new
- Name:
workspace-dispatch-pat-YYYY-MM-DD - Expiration: 12 months (max fine-grained allows)
- Resource owner:
chirag127 - Repository access: Only select repositories → pick
chirag127/workspaceonly - Permissions → Repository permissions:
- Contents: Read and write (required for
POST /repos/{owner}/{repo}/dispatches) - Metadata: Read-only (auto-selected, mandatory)
- Everything else: No access
- Contents: Read and write (required for
- Generate token. Copy value once — never shown again.
Store PAT
Umbrella .env
Add line to C:/D/oriz/.env:
WORKSPACE_DISPATCH_PAT=github_pat_xxxxxxxxxxxx
Then re-encrypt:
cd C:/D/oriz
sops -e .env > .env.enc
git add .env.enc
git commit -m "chore(env): rotate WORKSPACE_DISPATCH_PAT"
git push
Never commit plaintext .env (already gitignored — verify).
Each downstream repo
PAT=$(grep -E "^WORKSPACE_DISPATCH_PAT=" C:/D/oriz/.env | cut -d= -f2- | tr -d '\r"')
for repo in blog home me journal oriz-ncert-app; do
echo "$PAT" | gh secret set WORKSPACE_DISPATCH_PAT --repo chirag127/$repo --body -
done
Verify:
gh secret list --repo chirag127/blog
Should show WORKSPACE_DISPATCH_PAT.
Rotate PAT
Every 12 months or on suspected leak:
- Generate new PAT (steps above).
- Update
.env+ re-encrypt.env.enc. - Re-set on all downstream repos (loop above).
- Delete old PAT at https://github.com/settings/personal-access-tokens.
Verify PAT works
Manual dispatch test from any downstream repo shell:
gh api repos/chirag127/workspace/dispatches \
-f event_type=deploy \
-f 'client_payload[repo]=chirag127/blog' \
-f 'client_payload[class]=astro-site' \
-H "Authorization: token $WORKSPACE_DISPATCH_PAT"
Should return HTTP 204. Then check umbrella Actions tab — deploy run should be queued.
Anti-patterns
- Classic PAT with full
reposcope — too broad, leak = account-wide - PAT stored in downstream repo
.env— never, only in GitHub secrets - Shared PAT across users — one PAT per person; rotate on offboard
- PAT expiry >12mo — GitHub caps fine-grained at 12mo anyway