Neatbo.

Keep workflow declarations separate from live token access

Use explicit origins and unresolved states to make a local workflow review checkable without inventing runtime permissions.

Make the declaration review useful before drawing conclusions

A request to make permission declarations explicit is a concrete maintenance task. The Viper issue describes six jobs across three workflows; a local review can identify which jobs inherit a policy and which have their own mapping. It cannot prove the reporter's vulnerability claim, inspect a live token or make repository settings appear in a file that did not contain them.

T303 records one actual snapshot and its hash. That boundary is useful: an unknown default becomes a visible review item rather than a guessed grant, and a supplied default carries an unverified provenance marker. The output remains understandable when it is passed to a maintainer who knows the repository configuration.

Keep these conclusions distinct
EvidenceSupported conclusionFurther work
Explicit job mappingDeclared scopes, with omissions noneCheck whether each requested grant is necessary
No explicit policyUnknown default, or supplied contextVerify enterprise/organization/repository defaults
uses or conditionOriginal inert declaration and source positionReview referenced code and runtime event context
Exact needs cycleThese literal job IDs form a cycleCorrect the workflow and validate it in its real environment

Replacement is different from an accumulated list of grants

A workflow mapping and a job mapping are not two lists to union. In the checked fixture, deploy asks for id-token: write and does not inherit workflow contents: read. Its omitted contents is none. Empty uses {} and has an explicit all-none policy. A report that simply collects every permission word would lose that meaning.

Keep policy origin beside the selected policy. Also preserve global modes literally: scopes=null under read-all or write-all makes clear that the tool did not pretend to enumerate actual live access. A policy can be completely declared while runtime restrictions remain unknown.

An unresolved dependency deserves a row

Dropping a missing target or a matrix expression would make the graph look cleaner and the review less accurate. The complete export keeps all needs declarations and separates missing/expression issues from edges to exact existing IDs. It keeps each job/step use and original condition or matrix without executing them.

The six-job example contains a two-job cycle and a downstream dependent. Only cycleA/cycleB belong to that cycle. The downstream job still needs attention because it references an absent job and an unresolved expression. Different issues should remain distinguishable in the handoff.

  • Keep original job mappings, including run text, beside the derived fields.
  • Do not follow a local or remote action path to make a declaration report.
  • Treat user-supplied defaults as context, not a verified repository setting.
  • Use separate snapshots for separate workflows; do not infer cross-file runtime behavior.

A bounded preview can still deliver a complete review

A large workflow can produce more data than a narrow screen can show. The preview limits rows and cells; the downloaded JSON and CSV preserve all job records. Independent readback recomputes permission origins and every declaration/edge/use and checks every CSV row, including actual combined 1,000-job/10,000-edge/10,000-use sources.

Strict refusals are part of a reliable handoff. Unsupported collections, duplicate keys or cyclic aliases cannot become empty-looking success. Multiple YAML documents fail instead of silently ignoring later workflows. A source within 5MiB can still exceed the separate 10MiB download budget. On failure or actual cancellation, correct the source or rerun the same supported input; no partial success files are offered.

References

Tools in this category

Expand a tool to see its steps, options and supported formats, then open its workspace.

GitHub Actions permission and dependency auditInspect one local workflow's declared token permission policies, exact needs edges, cycles and action references with complete JSON and CSV.

Select a UTF8 YAML1.2 workflow snapshot. Resolve job permission mappings against the workflow declaration or explicit, unverified repository-default context. Keep omitted defaults unknown, preserve literal global modes and review exact declared dependencies and uses without executing expressions or contacting GitHub.

Steps

  1. Choose one workflow YAML copied from your own repository.
  2. Leave unknown defaults selected unless you explicitly supply repository context; choose mapping only to parse the JSON box.
  3. Review permission origins, omitted-none scopes, missing or unresolved dependencies and exact cycle groups.
  4. Download full JSON and CSV with every original job declaration; review repository/runtime settings separately.

Available options

Repository-default context
Unknown · Declared read-all context · Declared write-all context · Explicit JSON mapping

Explicit user context only; no repository lookup or live verification.

Explicit default permission JSON
{}

Parsed only when JSON mapping is selected; the 4KiB text budget always applies. Mapping omissions become none.

Capabilities and limits

  • One file up to 5MiB; 100,000 resolved YAML value nodes, depth 64, 1,000 jobs, 10,000 declared needs and 10,000 uses. Default JSON up to 4KiB; complete JSON/CSV together 10MiB. All limits apply together. Preview only 200 jobs and 2,000 UTF16 characters per cell; downloads contain every record.
  • One YAML1.2 core document with unique string mapping keys, ordinary mappings/arrays/scalars and acyclic aliases only. yaml2.9.1 uses a weighted alias expansion guard of 50; this is not a promise to support 50 literal references. Custom/Set/binary/date tags, YAML1.1, cycles, duplicate keys, nonfinite or unsafe integer values and unsupported permission keys fail the whole review.
  • Permission keys are fixed to the 2026-10-07 profile. Job mappings replace workflow mappings; omitted scopes become none and {} is all-none. Missing defaults stay unknown. Supplied defaults remain unverified. read-all/write-all stay literal modes with no invented per-scope access.
  • This reads one provided snapshot, not a full workflow schema, security verdict or live token test. Fork/Dependabot/reusable-workflow/repository restrictions remain unknown. Matrix/conditions/needs expressions and job/step uses stay inert; no action fetching, repository edits, network requests or script execution. Cancellation discards all outputs.
Open GitHub Actions permission and dependency audit →