1. Paste one or more workflow files
Copy the contents of each file under .github/workflows/ you want checked. Add more blocks for more files — nothing here reads your repository, so pasting is how it sees anything.
Paste at least one workflow file above and click Check.
Findings
| File : Line | Job | Status | Detail |
|---|
Prefer a CLI, or want this in your own CI?
Same logic, zero dependencies, one file:
python3 check.py # scan .github/workflows under the current directory
python3 check.py /path/to/repo # scan a specific checkout
python3 check.py --format json # machine-readable
python3 check.py --fail-on-risk # exit 2 if any fork-exposed job is found
Get check.py from the repo — stdlib only, nothing to install, no network calls. Wire --fail-on-risk into your own CI to block a newly-added exposed job before it merges.
Common questions
Why is a self-hosted runner risky on a public repository?
GitHub's own documentation recommends against using self-hosted runners on public repositories, because a workflow triggered by pull_request runs the workflow file from the pull request's own branch. Anyone who can open a PR against your repository can edit that workflow file and have their own steps execute directly on your runner machine.
Is pull_request_target or workflow_run just as risky as pull_request?
Differently risky. pull_request_target and workflow_run always run the workflow file from your base branch, not the fork's, so a stranger cannot rewrite the steps that execute. But both still respond to a fork-influenced event, often with repository secrets available, and a self-hosted job that also checks out and builds the fork's code still runs that code on infrastructure you own rather than an ephemeral GitHub-hosted VM. This tool flags all four risky triggers and names which one matched so you can judge the specific case.
Does this tool know whether my repository is actually public?
No. It makes no network calls of any kind and never checks your repository's visibility, required-approval settings, or whether an organization runner group is actually self-hosted. It flags the pattern in the workflow file; whether that pattern is actually exploitable on your repository is for you to confirm.
Does a clean scan mean my self-hosted runners are safe?
No. This checks one specific, narrow pattern: the literal self-hosted label combined with one of four documented risky triggers. It does not evaluate runner group names, network segmentation, ephemeral vs persistent runners, or anything about how the runner machine itself is hardened.
What should I do about a flagged job?
Move the job to a GitHub-hosted runner, restrict the workflow's trigger to events a fork cannot raise (push to a protected branch, workflow_dispatch, schedule), or require manual approval for every workflow run from an outside collaborator — GitHub's own setting for this is under Settings → Actions → General → "Fork pull request workflows".
More: why self-hosted runners and public repositories don't mix, and how to fix it.
Already using a runtime monitor on your runners? See this checker vs. StepSecurity's Harden-Runner.
Reviewing workflow files yourself instead? See this checker vs. reviewing workflows by eye.