Help us improve
Share bugs, ideas, or general feedback.
From github-it-admin
Re-mint CLAUDE_CODE_OAUTH_TOKEN via `claude setup-token` and dual-write to gh org + repo. Use when rotating the Claude Code OAuth token (quarterly per docs/operator-runbooks/secret-rotation.md, immediately on compromise, or when switching the active identity between admin-jadecli and alex-jadecli). Wraps the manual flow used 2026-05-18 into a reusable scaffold.
npx claudepluginhub subagentceo/knowledge-engineering --plugin github-it-adminHow this skill is triggered — by the user, by Claude, or both
Slash command
/github-it-admin:claude-oauth-rotateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Quarterly rotation per `docs/operator-runbooks/secret-rotation.md`.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
docs/operator-runbooks/secret-rotation.md./install-github-app (which writes the repo-scope secret; this skill ensures org-scope matches).claude setup-token opens a browser for OAuth approval — it can't be driven by an agent. The script scripts/rotate.sh therefore implements the operator-paste pattern (same as plugins/macos-it-admin/skills/turbopuffer-crud):
claude setup-token in a terminal; copies the printed token.scripts/rotate.sh.pbpaste (macOS clipboard) — never read -p, which would print the prompt to terminal scrollback.gh secret set for both org and repo scope.The value never enters Claude's context. This is the exact pattern used successfully on 2026-05-18 to rotate from admin-jadecli to alex-jadecli.
# Step 1: in a terminal, run claude setup-token (interactive; browser opens):
claude setup-token
# → approve in browser, token prints in terminal, copy to clipboard
# Step 2: run this script (reads from clipboard, dual-writes, wipes):
bash "${CLAUDE_PLUGIN_ROOT}/skills/claude-oauth-rotate/scripts/rotate.sh"
The script:
CLAUDE_CODE_OAUTH_TOKEN value from pbpaste>= 50 chars; 41 was the wrong-thing-copied signature from the 2026-05-18 incident)gh secret set --org ${user_config.gh_org} --visibility selected --repos ${user_config.gh_repo}gh secret set --repo ${user_config.gh_org}/${user_config.gh_repo}printf '' | pbcopy)gh secret list so operator can confirm both movedgh secret list --org "${user_config.gh_org}" --json name,updatedAt -q '.[] | select(.name=="CLAUDE_CODE_OAUTH_TOKEN")'
gh secret list --repo "${user_config.gh_org}/${user_config.gh_repo}" --json name,updatedAt -q '.[] | select(.name=="CLAUDE_CODE_OAUTH_TOKEN")'
Both timestamps should match (or org should be newer than repo, never the inverse, since repo-scope wins in resolution per gh docs).
Don't. The Claude Code Action workflows in this repo (claude.yml, claude-code-review.yml) hard-reference secrets.CLAUDE_CODE_OAUTH_TOKEN. Deleting causes 401s on every CI run. To "revoke" — re-mint via CREATE (which overwrites the old value, invalidating it upstream via Anthropic's session-rotation behavior).
pbpaste exclusively.code query param, not the exchanged token. Real tokens are 50+ chars. Script aborts on < 50.gh secret list. Operator visually confirms both moved./tmp (matches the 2026-05-18 pattern); skip self-delete when running from the plugin tree (the script there is reusable).| ID | Outcome | Verified by |
|---|---|---|
| OIT2-oauth-1 | Script reads only from clipboard (pbpaste), never read -p | src/lib/github-it-admin-plugin.test.ts |
| OIT2-oauth-2 | Asserts length >= 50 chars before piping to gh secret set | same test |
| OIT2-oauth-3 | Dual-writes to both org and repo | same test |
| OIT2-oauth-4 | Clipboard wiped after use | same test |
@cite docs/operator-runbooks/secret-rotation.md @cite docs/decisions/2026-05-17-secret-store-tiers.md (OSEC2) @cite vendor/anthropics/code.claude.com/docs/en/github-actions.md (OAuth setup section) @cite https://github.com/anthropics/claude-code-action/blob/main/docs/setup.md