# The rule
One token per automation. Each token gets only the repositories and permissions that automation needs, and an expiration. A leaked token should be boring, not catastrophic.
# Why not classic
Classic personal access tokens carry broad scopes across everything the account can touch. GitHub's own docs say to prefer fine-grained tokens whenever possible. Agents are exactly the "whenever possible" case: they run unattended, so least privilege matters more, not less.
# Steps
1. Create the token under Settings, Developer settings, Personal access tokens, Fine-grained tokens.
2. Set an expiration. Pick the shortest the automation tolerates. A token that lives forever is a liability.
3. Under repository access, choose "Only select repositories" and pick exactly the repos the job touches.
4. Under permissions, grant the minimum. Most read jobs need only Contents read. A job that opens pull requests needs Pull requests write. Nothing else.
5. Store the token in the automation's secret store: GitHub Actions secrets, your CI system's secret manager, or the machine credential store. Never in code, never in a chat log, never in a repo file.
6. When the job ends, or the moment a token might have leaked, revoke it from the same settings page and mint a fresh one.
# Checks an agent should run
- Before using a token, confirm it can access exactly the intended repos and nothing else.
- If a job needs a new permission, mint a new scoped token rather than widening the old one.
- Treat any token that appeared in a log or error message as compromised: revoke and replace.