Varje GitHub Actions-jobb får en token. GitHub skapar en ny GITHUB_TOKEN i början av varje jobb, avgränsad till repot där arbetsflödet finns, och varje steg i jobbet kan använda den. Vad den kan göra beror på inställningar som många team aldrig har tittat på, och på äldre repon är svaret fortfarande ”skriva till nästan allt”.

Det spelar roll när något i jobbet blir skadligt. I Nx-komprometteringen ”s1ngularity” i augusti 2025 hade repots token fortfarande läs- och skrivbehörighet. En injektion i ett pull_request_target-arbetsflöde använde den för att utlösa publiceringsarbetsflödet, som läckte npm-tokenen som användes för att publicera skadliga versioner av Nx. En skrivskyddad token hade stoppat det steget.

Det här inlägget går igenom hur tokenens behörigheter sätts, vad varje vanlig uppgift behöver och hur du hittar minimum för dina arbetsflöden.

Vad GITHUB_TOKEN är

GITHUB_TOKEN är en installationstoken för GitHub Actions-appen. Några egenskaper är lätta att missa:

  • Den finns oavsett om du använder den eller inte. Arbetsflöden refererar till den som secrets.GITHUB_TOKEN, men vilken action som helst kan läsa den via kontexten github.token utan att få den skickad till sig.
  • Den skrivs till disk som standard. actions/checkout sparar tokenen för senare git-kommandon om du inte sätter persist-credentials: false. Före v6 hamnade den i .git/config; v6 flyttade den till en separat fil under $RUNNER_TEMP. 2024 hittade Unit 42:s ArtiPACKED-forskning tokens som läckte via artefakter som innehöll .git/config.
  • Den upphör att gälla med jobbet. På GitHub-hostade runners innebär det högst 6 timmar, jobbets tidsgräns. På egenhostade runners kan den förnyas i upp till 24 timmar.

Eftersom tokenen alltid finns där är det enda du styr hur mycket den kan göra.

Standardläget: permissive eller restricted

Varje enterprise, organisation och repo har ett standardläge för tokenen:

  • Permissive: läsa och skriva för varje behörighet.
  • Restricted: skrivskyddad åtkomst till contents och packages, inget annat.

Sedan den 2 februari 2023 har nya enterprises, organisationer och repon restricted som standard. Ändringen rörde inte befintliga, så varje repo eller organisation som skapades före det datumet behåller permissive som standard om ingen ändrat det. Om en högre nivå väljer restricted kan nivåerna under den inte välja permissive.

Kontrollera det under Settings → Actions → General → Workflow permissions, först på organisationsnivå. Samma avsnitt har Allow GitHub Actions to create and approve pull requests, som bör vara avstängd om inget arbetsflöde behöver den.

Nyckeln permissions

Nyckeln permissions i ett arbetsflöde justerar tokenen utifrån standardläget. Den fungerar på två nivåer:

permissions:
  contents: read

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

Reglerna:

  • Jobbnivå åsidosätter arbetsflödesnivå. Sätt arbetsflödets standard till skrivskyddad och höj behörigheterna bara i de jobb som behöver det.
  • Allt du inte listar blir none. Så fort du anger en behörighet tas alla andra bort. permissions: {} tar bort alla.
  • Värdena är read, write eller none. write inkluderar read. read-all och write-all sätter allt på en gång; undvik write-all.

De tillgängliga behörigheterna, per september 2026:

BehörighetStyr
actionsArbetsflödeskörningar, artefakter och cachar
artifact-metadataMetadataposter för artefakter (ersatte contents för dessa API:er 2026)
attestationsArtefaktattesteringar
checksCheck runs och check suites
code-qualityKodkvalitetsresultat, till exempel täckningsrapporter
contentsRepots innehåll, commits, grenar, taggar och releaser
deploymentsDriftsättningar
discussionsDiscussions
id-tokenBegäran av en OIDC-token (endast write eller none)
issuesIssues och kommentarer
packagesGitHub Packages, inklusive containerregistret
pagesGitHub Pages-byggen
pull-requestsPull requests, etiketter och granskningar
security-eventsVarningar från code scanning och SARIF-uppladdningar
statusesCommit-statusar
vulnerability-alertsDependabot-varningar (endast read eller none)

När ett jobb saknar en behörighet det behöver misslyckas API-anropet med 403 Resource not accessible by integration. Det felet är signalen att lägga till den enda behörighet som steget behöver, inte att byta till write-all.

Vad vanliga uppgifter behöver

UppgiftBehörigheter
Checka ut kodcontents: read
Skapa en release eller pusha en taggcontents: write
Kommentera en issue eller pull requestissues: write (kommentarer på pull requests går via issues-API:et)
Lägga till etiketter eller granskningar i en pull requestpull-requests: write
Autentisera mot en molnleverantör med OIDCid-token: write
Skapa artefaktattesteringarid-token: write, attestations: write, contents: read, plus packages: write för containeravbilder
Pusha en avbild till GitHub Container Registrypackages: write
Ladda upp SARIF till code scanningsecurity-events: write
Driftsätta GitHub Pages från ett arbetsflödepages: write, id-token: write

De flesta test- och byggjobb behöver inget utöver contents: read.

Forkar, pull_request_target och Dependabot

  • Pull requests från forkar får en skrivskyddad token vid händelsen pull_request, oavsett vad arbetsflödet begär, om inte en administratör slår på ”Send write tokens to workflows from pull requests”. Låt den vara avstängd.
  • pull_request_target får en token för läsning och skrivning även för pull requests från publika forkar. Det är därför den ligger bakom många av de mest kända tokenstölderna: Nx-komprometteringen, Ultralytics-komprometteringen i december 2024 och komprometteringen av Trivy-actionen i mars 2026 började alla med ett pull_request_target-arbetsflöde. GitHub stramar åt det: sedan juli 2026 vägrar actions/checkout som standard att checka ut fork-kod i dessa arbetsflöden, och från och med den 2 november 2026 kommer pull_request_target att vara inaktiverat som standard i publika repon utan egen policy.
  • Dependabots pull requests behandlas som forkar: en skrivskyddad token och inga Actions-hemligheter. Om du väger andra uppdateringsverktyg, se alternativ till Dependabot.

Så hittar du minsta möjliga behörigheter

Du behöver inte räkna ut det genom att läsa varje actions källkod:

  • GitHub Security Labs actions-permissions övervakar hur ett arbetsflöde använder sin token och rekommenderar minsta möjliga behörigheter. Det är i publik beta.
  • OpenSSF Scorecards Token-Permissions-kontroll flaggar arbetsflöden som inte sätter skrivskyddade behörigheter på översta nivån. Kontrollen klassas som hög risk.
  • zizmor, en statisk analysator för arbetsflöden, flaggar överdrivna behörigheter eller standardbehörigheter och utcheckningar som sparar autentiseringsuppgifter.
  • StepSecuritys Secure-Repo och Harden-Runner rekommenderar behörigheter på jobbnivå utifrån en kunskapsbas om actions och utifrån de API-anrop ett jobb gör.

En praktisk utrullning: sätt organisationens standard till restricted, lägg till permissions: contents: read högst upp i varje arbetsflöde och kör arbetsflödena. De som misslyckas med Resource not accessible by integration visar exakt vilket jobb som behöver vilken extra behörighet.

Där CRACI passar in

Minsta behörighet begränsar vad en stulen token kan göra. Det hindrar inte att den stjäls, och jobbets övriga hemligheter, som npm-tokens och molnuppgifter, är lika utsatta.

CRACI kör dina GitHub Actions-jobb på sina egna runners. Du ändrar runs-on till craci; GITHUB_TOKEN, nyckeln permissions och dina repoinställningar fungerar som tidigare, eftersom GitHub fortfarande utfärdar tokenen. Det CRACI tillför finns på runnern: en egress-policy som avgör vilka värdar ett jobb får nå, valideras innan jobbet startar och blockerar vid fel, och en registrering av varje paket som jobbet hämtade, med en spårning av dess nätverksanslutningar. Om skadlig kod i ett jobb ändå får tag i en token begränsar policyn vart den kan skicka den, och registreringen visar vad som hände.

För resten av jobbets hemligheter, se hemligheter i GitHub Actions: så läcker de och så låser du dem. Boka en demo för att se registreringen av ett av dina egna byggen.