← GitHub Actions secrets: inherit Check

GitHub Actions secrets: inherit Check vs. reviewing workflows by eye

Finding the line secrets: inherit in a workflow file takes no special skill. Deciding what it actually exposes -- whether the call it sits on reaches outside the repository, and whether the job is one a stranger's fork can trigger -- is the part that is easy to get wrong under a quick read. This page names no product or company; "reviewing by eye" is the generic habit every maintainer already has, not a competing tool.

Where a careful read holds up, and where it slips

secrets: inherit does not hide -- it is one line, and a reviewer who knows to look for it will find every instance in a file. What is harder to hold in your head while scanning a real workflow is what each instance actually means. A reusable-workflow call is external only if its uses: value names another repository (owner/repo/.github/workflows/file.yml@ref) rather than a local path (./.github/workflows/file.yml) -- easy to conflate when the line wraps or sits several jobs away from the secrets: inherit it governs. And the fork-reachability question depends on a trigger declared once at the top of the file, under on:, which has to be carried in mind while reading down through every job below it -- easy to lose track of in a workflow with several unrelated jobs, especially when the risky job's name gives no hint that it is the one at risk.

Where to answer each question.
CaseReviewing by eyeThis tool
Spotting that a job uses secrets: inherit at allEasy to catch -- one distinctive lineCatches it the same way
Telling a local reusable-workflow call (./.github/workflows/file.yml) from an external one (owner/repo/…@ref)Easy to misread when the line wraps or sits jobs away from the secrets: inherit lineRe-parses the exact uses: value for every secrets: inherit line found
Connecting a job to a pull_request_target/workflow_run trigger declared at the top of a long fileEasy to lose track of while reading down through unrelated jobsChecks the whole file's trigger against every secrets: inherit line, however far apart they sit
A repository with a dozen workflow files, each with its own reusable-workflow callsRe-reading all of them for both patterns, every time a workflow changes, is tedious and easy to shortcutPaste as many files as you have, or run check.py across the whole directory
Blocking a newly-added finding before it mergesDepends on a human noticing it in reviewcheck.py --fail-on-risk gives a real exit code from the same classification, wired into your own CI

The two are complementary, not competing: this tool does not decide whether a called workflow is actually trustworthy, or whether a fork-reachable job's blast radius matters in your specific setup -- it replaces the tedious, error-prone part, which is re-checking every uses: value and every trigger declaration each time a workflow file changes.

Run the free secrets: inherit check

Common questions

What does reviewing a workflow for secrets: inherit by eye actually catch?

secrets: inherit is one distinctive line, and a reviewer who knows to look for it will find every occurrence in a file without much effort. That recognition is real, and this tool starts from the same line -- it does not find a secrets: inherit call a careful reader would have missed.

Why is telling an external reusable-workflow call from a local one easy to get wrong at a glance?

The difference between uses: ./.github/workflows/build.yml and uses: some-org/shared-workflows/.github/workflows/build.yml@v2 is a leading ./ and an owner/repo prefix -- easy to miss when the uses: line is long, wrapped, or several jobs removed from the secrets: inherit line it governs. A reviewer scanning quickly for the string secrets: inherit can confirm the line exists without re-checking which uses: value the surrounding job actually calls, which is exactly the distinction that decides whether the finding is secrets-inherit-external-workflow at all. This tool re-reads the uses: value for every secrets: inherit line it finds, every time.

Why is the fork-trigger connection easy to miss even when the trigger is declared right there in the file?

pull_request_target and workflow_run are usually declared once, at the top of the file, under on:. The job carrying secrets: inherit can be dozens of lines below, in a workflow with several unrelated jobs. Holding "this file's trigger is untrusted" in mind while scanning down through every job's steps, for every workflow file in a repository, is the kind of bookkeeping that is easy to let slip -- especially on a workflow whose name or first job gives no hint that a later job is the one at risk. This tool checks the whole file's trigger against every secrets: inherit line it finds, regardless of how far apart they sit.

Does a clean result from this tool mean my repository's secret handling is safe?

No. It checks two specific, well-documented secrets: inherit patterns in one workflow file at a time. It does not evaluate whether a called reusable workflow is itself trustworthy, and it does not follow a local reusable workflow to see what it in turn calls -- both real ways a repository's secret handling can still be exposed after a clean scan.