{"record":{"id":"886b16132af61594","repo":"denoland/deno","slug":"provenance-generation-in-github-actions-requires","errorCode":null,"errorMessage":"Provenance generation in Github Actions requires 'id-token' permission","messagePattern":"Provenance generation in Github Actions requires 'id-token' permission","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/publish/provenance.rs","lineNumber":315,"sourceCode":"\n#[derive(Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ProvenanceBundle {\n  pub media_type: &'static str,\n  pub content: SignatureBundle,\n  pub verification_material: VerificationMaterial,\n}\n\npub async fn generate_provenance(\n  http_client: &HttpClient,\n  subjects: Vec<Subject>,\n) -> Result<ProvenanceBundle, AnyError> {\n  if !is_gha() {\n    bail!(\"Automatic provenance is only available in GitHub Actions\");\n  }\n\n  if gha_oidc_token().is_none() {\n    bail!(\n      \"Provenance generation in Github Actions requires 'id-token' permission\"\n    );\n  };\n\n  let slsa = ProvenanceAttestation::new_github_actions(subjects)?;\n\n  let attestation = serde_json::to_string(&slsa)?;\n  let bundle = attest(http_client, &attestation, INTOTO_PAYLOAD_TYPE).await?;\n\n  Ok(bundle)\n}\n\npub async fn attest(\n  http_client: &HttpClient,\n  data: &str,\n  type_: &str,\n) -> Result<ProvenanceBundle, AnyError> {\n  // DSSE Pre-Auth Encoding (PAE) payload","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/publish/provenance.rs#L297-L333","documentation":"Even inside GitHub Actions, an OIDC token only exists when the job declares `permissions: id-token: write` — the default `GITHUB_TOKEN` cannot mint one. `generate_provenance` bails with this message when `ACTIONS_ID_TOKEN_REQUEST_TOKEN` is missing or empty, i.e. the runner never injected an OIDC request token.","triggerScenarios":"Publishing in GitHub Actions with provenance enabled (default when an OIDC token is detectable) from a workflow/job without `id-token: write`, or where GitHub restricts OIDC (some enterprise policies, fork PRs).","commonSituations":"First provenance-enabled release from a workflow using default permissions; a workflow-level `permissions:` block that overrides the job's; pull_request runs from forks where OIDC tokens are unavailable.","solutions":["Add to the publishing job (or workflow) `permissions: id-token: write` plus `contents: read` as needed.","If OIDC is unavailable in your context (fork PR, enterprise policy), publish with `--no-provenance` or use `--token <JSR_TOKEN>`."],"exampleFix":"# .github/workflows/publish.yml (before)\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - run: deno publish   # error: requires 'id-token' permission\n# after\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n      contents: read\n    steps:\n      - run: deno publish","handlingStrategy":"validation","validationCode":"# CI step placed before `deno publish` in the publishing job\n- name: Check OIDC availability\n  run: |\n    [ -n \"$ACTIONS_ID_TOKEN_REQUEST_TOKEN\" ] || { \\\n      echo \"job cannot mint OIDC tokens — add permissions: id-token: write\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare `permissions: id-token: write, contents: read` on the publishing job (or workflow) from day one.","Watch for workflow-level `permissions:` blocks silently overriding job-level grants.","For fork PRs or enterprises with OIDC disabled, conditionally publish with `--no-provenance`."],"tags":["publish","provenance","github-actions","oidc","permissions"],"backgroundTag":"missing-oidc-permission","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}