The build system as an untrusted environment
The pipeline holds more privilege than any human in your organisation and reports to fewer dashboards. Treat it as untrusted and the findings stop arriving as surprises.
The problem
A build runner holds deploy credentials, cloud roles, package publishing tokens and sometimes production data. It executes code that arrived from a pull request. Very little of what it does is read by anyone.
The three failures that matter are not exotic. Someone edits a workflow to add a step that reads the environment. A third-party action is referenced by a mutable tag whose owner can repoint it at new code whenever they like. A release is published with no provenance and consumed inside a day.
None of those is a vulnerability in a dependency you can patch. All of them are ordinary-looking changes to the one system that holds the keys.
How Hanu approaches it
Feedback where the work already is
Findings return to the forge as a check run on the commit, a GitLab job, or a CircleCI or Jenkins step — four providers have live feedback modules. The developer sees the finding on the diff with the rule, the score and the contributing signals attached, at the point where the fix is still a five-minute change.
A hygiene rule and a correlation rule answer different questions
| Hygiene rule | Correlation rule | |
|---|---|---|
| Example | CI-WF-UNPINNED-ACTION | RULE-T2-014 |
| Input | one observation | observations across providers |
| Default state | off (opts.includeHygiene) | on |
| On a full organisation scan | thousands of hits | only when a chain forms |
| Useful on a pull request | yes | yes |
CI_WORKFLOW_TAMPER carries the commit, the workflow path and the actor, and marks repositories that hold deploy credentials. Joined with a credential becoming readable it produces a CRITICAL chain with both halves of the evidence attached — the shape of GhostAction, where 817 accounts and 3,325 secrets were involved and git history mining was the payload's second stage.
A mutable reference is a trust decision, so make it visible
- uses: some-org/setup-tool@v3 # mutable tag — the owner can repoint this
- uses: some-org/setup-tool@a91f3c2 # commit SHA — content-addressed, immutableThe check does not assume the publisher is hostile. It records that the reference is mutable, which repository it appears in, and whether that repository can reach a deploy credential — and leaves the policy decision with you rather than pretending there is only one right answer.
What you get
CI-01Workflow integrity, per repository
CI-02Action pinning as a gate, not a queue
CI-03Release and provenance gates
CI-04Evidence that quotes the build
Limits
Hanu reads what the pipeline produced and what changed inside it. It is not a build-time sandbox and does not intercept a malicious action mid-execution. The detection is that the change happened and that the credential was then used — both arriving as evidence you can act on rather than as a suspicion you have to argue about.
Provider coverage is four: GitHub, GitLab, CircleCI and Jenkins. Other systems can send webhooks in, but they will not get check-run feedback or job-level context, which is most of the value.
Self-hosted runners with no upstream audit trail give you less to correlate. If your CI system does not record who changed a workflow, no external tool can deduce it, and the honest recommendation is to fix that first.
Questions
Will this fail our builds?
What about actions that have no immutable ref?
Does the platform need write access to our repositories?
Can you detect secrets being read out of the runner environment?
Run it in your own account
One Docker Compose stack, your datastores, read-only credentials into your clouds. The Community edition is free to run in production.