Inspect local Actions permission policies and job dependencies
Review explicit policy origins, omitted scopes, exact dependencies and complete inert job declarations from one local YAML snapshot.
Start with one workflow you can identify
A maintainer reported missing permission declarations in six jobs across three Viper workflows. T303 handles that review one copied workflow at a time. Select the UTF8 YAML from your own checkout; no repository credentials, token or network access is needed. Repeat separately for the other workflows and keep their source hashes with the exported reviews.
The report preserves the workflow-level declarations and every original job mapping, including steps, run text, conditions and matrices. These are parsed data. Shell commands, HTML strings, local action paths and remote uses are neither run nor fetched. This output is a review record, not an edited workflow to commit.
| Mode | Review behavior | Evidence status |
|---|---|---|
| unknown | Missing workflow/job permissions stay unknown | No repository setting guessed |
| read-all / write-all | Keep the selected literal mode | User context remains unverified |
| mapping | Parse unique-key default JSON and fill omitted scopes with none | Explicit user context; no live lookup |
Read the selected policy before changing a file
A job declaration takes priority over the workflow declaration and supplied default context. An explicit mapping sets every omitted supported scope to none; an empty mapping sets them all to none. A job mapping therefore replaces the workflow mapping. The tool does not merge a workflow grant back into a job that omitted it.
In the checked six-job example, workflow contents: read and issues: write apply to build. Deploy explicitly requests id-token: write, so its contents and issues are none. Empty explicitly declares {}, leaving every scope none. The policy origin column distinguishes job, workflow, provided-default and unknown-default.
- The supported permission keys are fixed to the 2026-10-07 profile; an unknown future key fails rather than disappearing.
- id-token accepts write/none; vulnerability-alerts accepts read/none. Invalid access values fail the complete review.
- Global read-all/write-all stays a literal mode with scopes=null. It is not expanded into invented effective grants.
- The default JSON box is parsed only in mapping mode; its 4KiB UTF8 budget applies in every mode. Explicitly selected invalid context fails even when a workflow policy would take priority.
Separate real dependency edges from unresolved declarations
All declared needs remain in each job record. Only exact existing literal job IDs create dependency edges. Missing targets and expressions have distinct issues. Conditions, matrix declarations and job/step uses preserve their original text and positions; their runtime behavior is unknown.
The example has seven needs declarations and five existing edges. cycleA and cycleB form one exact strongly connected group. The downstream job after is not a cycle member; its missing target and expression remain two explicit issues. A self-edge forms a one-job cycle. This is a graph of declarations, not a simulation of which jobs execute.
| State | Meaning |
|---|---|
| permissionUnknown=true | No job/workflow declaration or supplied default selected |
| incomplete=true | Unknown policy, missing/expression dependency, uses, condition, matrix or cycle requires further context |
| runtimeAccessVerified=false | No live token access was tested, even when declarations are complete |
| runtimeRestrictionsUnknown=true | Repository, fork, Dependabot and reusable-workflow restrictions remain unverified |
Download the entire review and recover safely
The table contains at most 200 jobs and 2,000 UTF16 characters per cell. The summary explains the counts; complete JSON and CSV retain every job, original declaration, use reference and dependency. JSON also contains all graph edges, exact cycles, issues, default provenance and the source SHA256. A short table is not a partial export.
Local native tests deliver 1,000 jobs, 10,000 exact edges and 10,000 uses in one actual source, with all rows checked by a separate PyYAML reader and reachability oracle. A distinct source reaches exactly 10MiB of combined downloads; the next source byte exceeds the output budget. Native progress cancellation discards output, and the same supported input recovers. Browser acceptance is maintained separately by the controller.
- One input: 5MiB, 100,000 resolved value nodes, depth 64, 1,000 jobs, 10,000 needs and 10,000 uses; default JSON 4KiB; two downloads combined 10MiB. All limits apply together.
- Only YAML1.2 core, unique string keys and ordinary finite safe-number/string/boolean/null/mapping/array data are supported. YAML1.1, multiple documents, custom/Set/binary/date tags, unsafe integers, duplicate keys and cyclic aliases fail the whole task.
- Acyclic aliases use yaml2.9.1's weighted expansion guard of 50. It is not a literal promise of 50 references; the tested one-scalar anchor accepts 49 references and rejects the next.
- On error, correct the unsupported structure or actual limit and rerun. On cancellation, no partial success artifacts remain. Originals are never edited.
- Full schema validity, dependency vulnerabilities, permission necessity, live token access and automated repository remediation are outside this review.
References
- Maintainer task: six jobs missing explicit permissions
Original issue body read 2026-10-07; it concerns three workflows. This tool reviews one supplied snapshot at a time and does not repeat the author's live security claims.
- GitHub workflow permission and needs syntax
Primary permission table, omitted-none behavior, precedence and needs sections read 2026-10-07. Runtime restrictions remain outside the local snapshot.
- yaml parser conversion and alias guard
Primary parsing/Map/alias options read 2026-10-07; production pins ISC yaml2.9.1 and rejects unsupported collections and directives.
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
- Choose one workflow YAML copied from your own repository.
- Leave unknown defaults selected unless you explicitly supply repository context; choose mapping only to parse the JSON box.
- Review permission origins, omitted-none scopes, missing or unresolved dependencies and exact cycle groups.
- 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.