Elke GitHub Actions-job krijgt een token. GitHub maakt aan het begin van elke job een nieuw GITHUB_TOKEN aan, beperkt tot de repository waarin de workflow staat, en elke stap in de job kan het gebruiken. Wat het kan, hangt af van instellingen waar veel teams nooit naar hebben gekeken, en op oudere repositories is het antwoord nog steeds "naar bijna alles schrijven".
Dat is van belang wanneer iets in de job kwaadaardig wordt. Bij de Nx-compromittering "s1ngularity" van augustus 2025 had het token van de repository nog lees- en schrijfrechten. Een injectie in een pull_request_target-workflow gebruikte het om de publicatieworkflow te starten, waardoor het npm-token lekte waarmee kwaadaardige versies van Nx werden gepubliceerd. Een alleen-lezentoken had die stap tegengehouden.
Dit bericht behandelt hoe de rechten van het token worden ingesteld, wat elke veelvoorkomende taak nodig heeft, en hoe u het minimum voor uw workflows vindt.
Wat GITHUB_TOKEN is
GITHUB_TOKEN is een installation access token van de GitHub Actions-app. Een paar eigenschappen worden makkelijk over het hoofd gezien:
- Het bestaat of u het nu gebruikt of niet. Workflows verwijzen ernaar als
secrets.GITHUB_TOKEN, maar elke action kan het via de contextgithub.tokenlezen zonder dat het wordt doorgegeven. - Het wordt standaard naar schijf geschreven.
actions/checkoutbewaart het token voor latere git-opdrachten, tenzij upersist-credentials: falseinstelt. Vóór v6 ging het naar.git/config; v6 verplaatste het naar een apart bestand onder$RUNNER_TEMP. In 2024 vond het ArtiPACKED-onderzoek van Unit 42 tokens die lekten via artefacten die.git/configbevatten. - Het verloopt met de job. Op door GitHub gehoste runners betekent dat maximaal 6 uur, de tijdslimiet van een job. Op self-hosted runners kan het tot 24 uur worden vernieuwd.
Omdat het token er altijd is, kunt u alleen bepalen hoeveel het kan.
De standaard: permissive of restricted
Elke enterprise, organisatie en repository heeft een standaard voor het token:
- Permissive: lezen en schrijven voor elk recht.
- Restricted: alleen-lezen op
contentsenpackages, verder niets.
Sinds 2 februari 2023 staan nieuwe enterprises, organisaties en repositories standaard op restricted. De wijziging raakte bestaande niet, dus elke repository of organisatie die daarvoor is aangemaakt, houdt de permissive standaard tenzij iemand die wijzigde. Kiest een hoger niveau voor restricted, dan kunnen de niveaus eronder niet voor permissive kiezen.
Controleer het onder Settings → Actions → General → Workflow permissions, eerst op organisatieniveau. In dezelfde sectie staat Allow GitHub Actions to create and approve pull requests, wat uit moet blijven tenzij een workflow het nodig heeft.
De permissions-sleutel
De sleutel permissions in een workflow past het token aan ten opzichte van de standaard. Hij werkt op twee niveaus:
permissions:
contents: read
jobs:
release:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@<full-commit-sha>
De regels:
- Jobniveau gaat boven workflowniveau. Stel de workflowstandaard in op alleen-lezen en verhoog rechten alleen in de jobs die ze nodig hebben.
- Alles wat u niet vermeldt, wordt
none. Zodra u één recht instelt, worden alle andere verwijderd.permissions: {}verwijdert ze allemaal. - Waarden zijn
read,writeofnone.writeomvatread.read-allenwrite-allstellen alles tegelijk in; vermijdwrite-all.
De beschikbare rechten, per september 2026:
| Recht | Bepaalt |
|---|---|
actions | Workflowruns, artefacten en caches |
artifact-metadata | Metadatarecords van artefacten (verving contents voor deze API's in 2026) |
attestations | Artefactattestaties |
checks | Check runs en check suites |
code-quality | Resultaten van codekwaliteit, zoals dekkingsrapporten |
contents | Repository-inhoud, commits, branches, tags en releases |
deployments | Deployments |
discussions | Discussions |
id-token | Een OIDC-token aanvragen (alleen write of none) |
issues | Issues en opmerkingen |
packages | GitHub Packages, inclusief het containerregister |
pages | GitHub Pages-builds |
pull-requests | Pull requests, labels en reviews |
security-events | Code scanning-meldingen en SARIF-uploads |
statuses | Commitstatussen |
vulnerability-alerts | Dependabot-meldingen (alleen read of none) |
Als een job een recht mist dat hij nodig heeft, mislukt de API-aanroep met 403 Resource not accessible by integration. Die fout is het signaal om het ene recht toe te voegen dat de stap nodig heeft, niet om over te stappen op write-all.
Wat veelvoorkomende taken nodig hebben
| Taak | Rechten |
|---|---|
| Code uitchecken | contents: read |
| Een release maken of een tag pushen | contents: write |
| Reageren op een issue of pull request | issues: write (opmerkingen op pull requests lopen via de issues-API) |
| Labels of reviews aan een pull request toevoegen | pull-requests: write |
| Authenticeren bij een cloudprovider met OIDC | id-token: write |
| Artefactattestaties maken | id-token: write, attestations: write, contents: read, plus packages: write voor containerimages |
| Een image naar GitHub Container Registry pushen | packages: write |
| SARIF uploaden naar code scanning | security-events: write |
| GitHub Pages deployen vanuit een workflow | pages: write, id-token: write |
De meeste test- en buildjobs hebben niet meer nodig dan contents: read.
Forks, pull_request_target en Dependabot
- Pull requests vanuit forks krijgen bij het event
pull_requesteen alleen-lezentoken, wat de workflow ook vraagt, tenzij een beheerder "Send write tokens to workflows from pull requests" inschakelt. Laat dat uit. pull_request_targetkrijgt een lees- en schrijftoken, zelfs voor pull requests vanuit openbare forks. Daarom zit het achter veel van de bekendste tokendiefstallen: de Nx-compromittering, de Ultralytics-compromittering in december 2024 en de compromittering van de Trivy-action in maart 2026 begonnen allemaal met eenpull_request_target-workflow. GitHub perkt het in: sinds juli 2026 weigertactions/checkoutstandaard forkcode uit te checken in deze workflows, en vanaf 2 november 2026 wordtpull_request_targetstandaard uitgeschakeld voor openbare repositories zonder eigen beleid.- Dependabot-pull requests worden behandeld als forks: een alleen-lezentoken en geen Actions-secrets. Weegt u andere updatetools af, zie dan alternatieven voor Dependabot.
Hoe u de minimale rechten vindt
U hoeft dit niet uit te zoeken door de broncode van elke action te lezen:
- actions-permissions van GitHub Security Lab monitort hoe een workflow zijn token gebruikt en beveelt de minimale rechten aan. Het is in openbare bèta.
- De Token-Permissions-controle van OpenSSF Scorecard markeert workflows die op het hoogste niveau geen alleen-lezenrechten instellen. De controle krijgt een hoge risicoscore.
- zizmor, een statische analyzer voor workflows, markeert buitensporige of standaardrechten en checkouts die inloggegevens bewaren.
- Secure-Repo en Harden-Runner van StepSecurity bevelen rechten op jobniveau aan op basis van een kennisbank van actions en de API-aanroepen die een job doet.
Een praktische uitrol: stel de organisatiestandaard in op restricted, voeg bovenaan elke workflow permissions: contents: read toe en draai de workflows. De workflows die mislukken met Resource not accessible by integration vertellen u precies welke job welk extra recht nodig heeft.
Waar CRACI in past
Least privilege beperkt wat een gestolen token kan doen. Het voorkomt niet dat het wordt gestolen, en de andere secrets in de job, zoals npm-tokens en cloudinloggegevens, zijn net zo blootgesteld.
CRACI draait uw GitHub Actions-jobs op eigen runners. U wijzigt runs-on in craci; GITHUB_TOKEN, de sleutel permissions en uw repository-instellingen werken zoals voorheen, omdat GitHub het token nog steeds uitgeeft. Wat CRACI toevoegt, zit op de runner: een egressbeleid dat bepaalt welke hosts een job mag bereiken, wordt gevalideerd voordat de job start en veilig dichtvalt, en een record van elk pakket dat de job heeft opgehaald, met een trace van zijn netwerkverbindingen. Krijgt kwaadaardige code in een job toch een token in handen, dan beperkt het beleid waar die het naartoe kan sturen, en toont het record wat er is gebeurd.
Zie voor de overige secrets van de job GitHub Actions-secrets: hoe ze lekken en hoe u ze afschermt. Boek een demo om het record van een van uw eigen builds te zien.
