Hver GitHub Actions-jobb får et token. GitHub lager et nytt GITHUB_TOKEN ved starten av hver jobb, avgrenset til repositoriet workflowen ligger i, og alle steg i jobben kan bruke det. Hva det kan gjøre, avhenger av innstillinger mange team aldri har sett på, og i eldre repositorier er svaret fortsatt «skrive til nesten alt».

Det får betydning når noe i jobben blir ondsinnet. I Nx «s1ngularity»-kompromitteringen i august 2025 hadde repositoriets token fortsatt lese- og skrivetillatelser. En injeksjon i en pull_request_target-workflow brukte det til å utløse publiseringsworkflowen, som lekket npm-tokenet som ble brukt til å publisere ondsinnede versjoner av Nx. Et skrivebeskyttet token ville ha stoppet det steget.

Dette innlegget tar for seg hvordan tokenets tillatelser settes, hva hver vanlig oppgave trenger, og hvordan du finner minimumet for workflowene dine.

Hva GITHUB_TOKEN er

GITHUB_TOKEN er et installasjonstilgangstoken for GitHub Actions-appen. Noen egenskaper er lette å overse:

  • Det finnes enten du bruker det eller ikke. Workflows viser til det som secrets.GITHUB_TOKEN, men enhver action kan lese det gjennom github.token-konteksten uten å få det sendt inn.
  • Det skrives til disk som standard. actions/checkout lagrer tokenet for senere git-kommandoer med mindre du setter persist-credentials: false. Før v6 havnet det i .git/config, og v6 flyttet det til en egen fil under $RUNNER_TEMP. I 2024 fant Unit 42s ArtiPACKED-forskning tokens som lekket gjennom artefakter som inkluderte .git/config.
  • Det utløper med jobben. På GitHub-hostede runnere betyr det maksimalt 6 timer, tidsgrensen for jobben. På selvhostede runnere kan det fornyes i opptil 24 timer.

Siden tokenet alltid er der, er det eneste du styrer, hvor mye det kan gjøre.

Standarden: permissive eller restricted

Hver enterprise, organisasjon og hvert repositorium har en standard for tokenet:

  • Permissive: lesing og skriving på alle tillatelser.
  • Restricted: skrivebeskyttet på contents og packages, ingenting annet.

Siden 2. februar 2023 har nye enterprises, organisasjoner og repositorier restricted som standard. Endringen berørte ikke eksisterende, så ethvert repositorium eller enhver organisasjon opprettet før den tid beholder permissive som standard med mindre noen endret det. Hvis et høyere nivå velger restricted, kan ikke nivåene under velge permissive.

Sjekk det under Settings → Actions → General → Workflow permissions, først på organisasjonsnivå. Samme seksjon har Allow GitHub Actions to create and approve pull requests, som bør være av med mindre en workflow trenger det.

permissions-nøkkelen

permissions-nøkkelen i en workflow justerer tokenet fra standarden. Den virker på to nivåer:

permissions:
  contents: read

jobs:
  release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<full-commit-sha>

Reglene:

  • Jobbnivå overstyrer workflow-nivå. Sett workflow-standarden til skrivebeskyttet, og hev tillatelsene bare i jobbene som trenger det.
  • Alt du ikke lister, blir none. Så snart du setter én tillatelse, fjernes alle andre. permissions: {} fjerner alle.
  • Verdiene er read, write eller none. write inkluderer read. read-all og write-all setter alt på én gang. Unngå write-all.

De tilgjengelige tillatelsene per september 2026:

TillatelseStyrer
actionsWorkflow-kjøringer, artefakter og cacher
artifact-metadataMetadataregistreringer for artefakter (erstattet contents for disse API-ene i 2026)
attestationsArtefakt-attestasjoner
checksCheck runs og check suites
code-qualityKodekvalitetsresultater, for eksempel dekningsrapporter
contentsRepositorieinnhold, commits, grener, tagger og utgivelser
deploymentsUtrullinger
discussionsDiskusjoner
id-tokenForespørsel om et OIDC-token (bare write eller none)
issuesIssues og kommentarer
packagesGitHub Packages, inkludert container-registeret
pagesGitHub Pages-bygg
pull-requestsPull requests, etiketter og gjennomganger
security-eventsCode scanning-varsler og SARIF-opplastinger
statusesCommit-statuser
vulnerability-alertsDependabot-varsler (bare read eller none)

Når en jobb mangler en tillatelse den trenger, feiler API-kallet med 403 Resource not accessible by integration. Den feilen er signalet til å legge til den ene tillatelsen steget trenger, ikke til å bytte til write-all.

Hva vanlige oppgaver trenger

OppgaveTillatelser
Sjekke ut kodecontents: read
Opprette en utgivelse eller pushe en taggcontents: write
Kommentere på en issue eller pull requestissues: write (kommentarer på pull requests går gjennom issues-API-et)
Legge til etiketter eller gjennomganger på en pull requestpull-requests: write
Autentisere mot en skyleverandør med OIDCid-token: write
Opprette artefakt-attestasjonerid-token: write, attestations: write, contents: read, pluss packages: write for container-images
Pushe et image til GitHub Container Registrypackages: write
Laste opp SARIF til code scanningsecurity-events: write
Rulle ut GitHub Pages fra en workflowpages: write, id-token: write

De fleste test- og byggejobber trenger ikke mer enn contents: read.

Forks, pull_request_target og Dependabot

  • Pull requests fra forks får et skrivebeskyttet token på pull_request-hendelsen, uansett hva workflowen ber om, med mindre en administrator slår på «Send write tokens to workflows from pull requests». La den være av.
  • pull_request_target får et token med lese- og skrivetilgang, selv for pull requests fra offentlige forks. Derfor ligger det bak mange av de mest kjente tokentyveriene: Nx-kompromitteringen, Ultralytics-kompromitteringen i desember 2024 og kompromitteringen av Trivy-actionen i mars 2026 startet alle med en pull_request_target-workflow. GitHub snevrer det inn: Siden juli 2026 nekter actions/checkout som standard å sjekke ut fork-kode i disse workflowene, og fra 2. november 2026 får offentlige repositorier uten egen policy pull_request_target deaktivert som standard.
  • Dependabot-pull requests behandles som forks: et skrivebeskyttet token og ingen Actions-hemmeligheter. Vurderer du andre oppdateringsverktøy, kan du se alternativer til Dependabot.

Slik finner du minimumstillatelsene

Du trenger ikke finne ut av dette ved å lese kildekoden til hver action:

  • GitHub Security Labs actions-permissions overvåker hvordan en workflow bruker tokenet sitt, og anbefaler minimumstillatelsene. Det er i offentlig beta.
  • OpenSSF Scorecards Token-Permissions-sjekk flagger workflows som ikke setter skrivebeskyttede tillatelser på toppnivå. Den vurderer sjekken som høy risiko.
  • zizmor, en statisk analysator for workflows, flagger for brede tillatelser eller standardtillatelser og checkouts som lagrer legitimasjon.
  • StepSecuritys Secure-Repo og Harden-Runner anbefaler tillatelser på jobbnivå ut fra en kunnskapsbase om actions og API-kallene en jobb gjør.

En praktisk utrulling: Sett organisasjonens standard til restricted, legg til permissions: contents: read øverst i hver workflow, og kjør workflowene. De som feiler med Resource not accessible by integration, forteller deg nøyaktig hvilken jobb som trenger hvilken ekstra tillatelse.

Der CRACI kommer inn

Minste privilegium begrenser hva et stjålet token kan gjøre. Det hindrer ikke at det blir stjålet, og de andre hemmelighetene i jobben, som npm-tokens og skylegitimasjon, er like utsatt.

CRACI kjører GitHub Actions-jobbene dine på egne runnere. Du endrer runs-on til craci, og GITHUB_TOKEN, permissions-nøkkelen og repositorieinnstillingene virker som før, fordi GitHub fortsatt utsteder tokenet. Det CRACI tilfører, ligger på runneren: en egress-policy som avgjør hvilke verter en jobb kan nå, valideres før jobben starter og blokkerer ved feil, og en registrering av hver pakke jobben hentet, med et spor av nettverkstilkoblingene. Hvis ondsinnet kode i en jobb likevel får tak i et token, begrenser policyen hvor den kan sende det, og registreringen viser hva som skjedde.

For resten av jobbens hemmeligheter, se GitHub Actions-hemmeligheter: slik lekker de og slik låser du dem ned. Book en demo for å se registreringen av et av dine egne bygg.