Dev.to Security πŸ” Cybersecurity πŸ‘ 0 πŸ“– 4 min read

Your workflow PR just widened its own permissions. Would anyone notice?

Most GitHub Actions changes look routine. You bump an action version, add a test, or rename a job. But a routine-looking PR can also include this: permissions: contents: read contents: write id-token: write That

Most GitHub Actions changes look routine. You bump an action version, add a test, or rename a job.

But a routine-looking PR can also include this:
permissions:

  • contents: read
  • contents: write
  • id-token: write

That job just gained write permissions and the ability to request an OIDC token.

It might be intentional. It might be necessary. But it deserves more attention than a version bumpβ€”and in a 300-line workflow, it’s easy to miss.

I built Remit to put those changes in front of the reviewer.
What Remit does
Remit is a GitHub Action and CLI that compares the workflows before and after a pull request. It adds annotations to lines that expand a workflow’s access or bring new code and inputs into a privileged job.

The question it helps answer is simple:

What can this workflow do after this PR that it couldn’t do before?

Remit flags changes such as:

  • More access: a job gains write permissions, OIDC, or access to new secrets.
  • A different execution context: a workflow adds a sensitive trigger such as pull_request_target, switches to a self-hosted runner, or changes deployment environments.
  • New risks in privileged jobs: a job with secrets or write access starts running third-party code, restoring caches, or retaining checkout credentials.
  • Untrusted PR content: a privileged workflow starts using pull request code or artifacts, including references passed through environment variables, step outputs, or action inputs. It also follows local composite actions and reusable workflows. A change inside .github/actions/setup/action.yml can be flagged even when no workflow file changes.

Existing permissions don’t generate repeat warnings just because they’re there. An unchanged contents: write stays quiet. A job gaining it gets a note.
Why not just use zizmor?
You should use zizmor. Remit is meant to work alongside it.

Tools such as zizmor audit workflow configuration for security issues. Remit focuses on what a pull request changes.

A job gaining a new secret or OIDC permission may be completely valid. There may be no insecure configuration to report. But a reviewer should still notice that the job now has access it didn’t have before.

That’s the gap Remit is built to cover.
I tested the overlap instead of guessing
I ran Remit, zizmor, poutine, and actionlint before and after 446 workflow-related commits across 30 repositories, counting only new findings.

Of Remit’s 233 findings, 172 had no related new finding from zizmor or poutine. That included 55 of 57 newly exposed secrets and every runner and environment change.

Those numbers measure different coverageβ€”not 172 confirmed vulnerabilities.

That first round also found problems in Remit itself: false positives around read-only permissions, a file-size limit that real workflows exceeded, and a nesting limit that was too low. I fixed them.

Then I froze the code and tested it on 448 commits from 30 repositories it hadn’t seen before.
Measure Result
Crashes 0
Commits fully analysed 97.5%
Incorrect findings in a random sample of 40 0
Correct but low-value findings 15–20%
Analysis time, 95th percentile 1.2 seconds

The low-value findings missed my target of 15% or less. One rule was treating some hardening changes as possible increases in access.

That rule is now fixed, but the fix needs a fresh test set before I can fairly claim a better result.

I also ran 4,409 planted-change test cases, covering 22 kinds of privilege change and eight kinds of harmless change. After correcting bugs in my test harness, every planted privilege change was detected and none of the harmless changes were flagged.

That validates the tested patterns across messy real workflows. It does not mean Remit catches every possible attack.
Outside review found things I missed
A reviewer found a real detection bypass involving GitHub’s expression handling. They also found a bug in my benchmark script: it counted a crashed zizmor run as β€œfound nothing,” which inflated two comparison figures.

Both issues are fixed. The figures above are the corrected ones.

That review also led to checks for privileged jobs starting to restore caches and checkouts dropping persist-credentials: false.

Fuzzing another 20,000 mutated workflows found a performance bug, which is fixed too.

The commit lists, scripts, and results are in benchmarks/ so the testing can be reproduced.
How it handles untrusted pull requests
The recommended workflow runs on pull_request with contents: read and no repository secrets.

It checks out the trusted base commit and reads the PR’s head as Git data. It does not execute code from the PR or make network calls during analysis. Its YAML parser is bundled and hash-verified.

The review job stays deliberately low-privilege.
What it doesn’t do
Remit helps reviewers. It doesn’t replace them, and its findings don’t fail your build.

It can’t inspect the contents of scripts your workflows run, code inside other repositories’ actions, or your repository’s default token permissions.

A PR can also edit the workflow that runs Remit. Pair it with CODEOWNERS and require the relevant approval for changes under .github/.
Try Remit on your next workflow PR
Copy the workflow template from the repository into .github/workflows/remit.yml. Findings appear in the PR’s Files changed tab and the job summary.

Or try the CLI:
pip install remit-actions

remit scan --repo . --base main --head my-branch --format markdown

There’s also an audit command for existing pwn-request patterns:
remit audit --repo .

Remit is still a young, one-maintainer project. The feedback I’d value most is practical: Did it flag something that didn’t matter, or miss something that did?

Open an issue with a small example or a link, and include the rule ID when there is one. Those reports help make the next review more useful.

πŸ“° Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.