GITHUB_TOKEN en Actions: permissions mínimas, no un PAT de admin
Resumen
Cada job de GitHub Actions recibe GITHUB_TOKEN. El bloque permissions recorta contents, pull-requests, id-token. Un agente que escribe workflows con contents: write por default abre la puerta a un PR que pushea a main. Least privilege. Docs automatic token authentication.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
Un workflow nuevo con permissions: contents: write “porque checkout” es el default perezoso. actions/checkout funciona con read. Write hace que un job comprometido (script de un PR fork, o un action de terceros) pueda commitear con el token del repo.
GITHUB_TOKEN lo inyecta Actions. Caduca al terminar el job. Un PAT de admin en secrets no caduca y salta branch protection si el dueño es admin. No lo uses para CI de tests. Ver secretos.
El curso instalar un agente no cubre YAML de Actions. gh pr es el delivery; el workflow no mergea.
El bloque mínimo
permissions:
contents: read
A nivel workflow o job. Si el job comenta en el PR:
permissions:
contents: read
pull-requests: write
OIDC a la nube: id-token: write sin contents write. Deploy: el job de deploy, no el de lint.
packages: read si tiras de ghcr. actions: read raro. security-events: write solo code scanning.

Qué no hace el agente
permissions: write-all- PAT
GH_TOKENcon scope repo para unpnpm test persist-credentials: trueen checkout de un workflow que luego corre código de PR (el default de checkout persiste el token en.git; en forks hay que pensarlo)pull_request_target+ checkout del PR + token write (clásico de inyección)
Forks: GITHUB_TOKEN de pull_request no tiene write a secrets del repo. No “arregles” con pull_request_target para tener secrets.
Receta AGENTS.md
New workflows: permissions: contents: read unless a job proves it needs more.
Never add a PAT for CI that GITHUB_TOKEN covers.
Never write-all.
Do not add pull_request_target without a security review.

FAQ
¿Checkout necesita write? No para clonar. Write si el job pushea tags/commits (release). Ese job está aislado.
¿Default del org es read? Muchas orgs ya pusieron default read. El YAML explícito gana y se lee en el PR.
¿Matrix? permissions del job aplican a cada shard.
¿Reusable workflows? El caller y el callee tienen permissions distintas; no asumas write heredado.
Si un action de marketplace pide contents: write para “comentar un PR”, es el olor equivocado: eso es pull-requests: write. Pide el mínimo o no lo uses. Un agent que copia un workflow de un gist con write-all no “ahorra tiempo”: copia un agujero.
Verificado 2026-09-03 contra GitHub Docs — Automatic token authentication / assigning permissions to jobs.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git status para coding agents: porcelain, XY, no el long

Reusable workflows: workflow_call, no copies el YAML entre repos

schedule (cron) en GitHub Actions: UTC, no cada minuto
