Skip to content

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.

CI/CD security platformworkflow tampering detectionGitHub Actions security

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 ruleCorrelation rule
ExampleCI-WF-UNPINNED-ACTIONRULE-T2-014
Inputone observationobservations across providers
Default stateoff (opts.includeHygiene)on
On a full organisation scanthousands of hitsonly when a chain forms
Useful on a pull requestyesyes
Same repository, same evidence, different question: is this built well, versus is this being used against us.

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, immutable

The 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
Every workflow change is recorded with its commit, path and actor. Repositories holding deploy credentials are flagged sensitive, which is what makes an identical edit a different severity in two different places.
CI-02Action pinning as a gate, not a queue
The unpinned-action check runs on the pull-request gate and stays off the organisation scan, because the finding is worth acting on exactly once — in the diff, before the reference reaches main.
CI-03Release and provenance gates
Freshness windows of 24 hours for dependencies and 72 hours for your own packages, with provenance status recorded. A gap contributes to the score only alongside another anomaly, which is what keeps the signal usable.
CI-04Evidence that quotes the build
Findings name the workflow path, the step and the actor, so a reviewer does not have to reconstruct what the runner did from a log they were not going to read.

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?
Only where you enable it. The gate is configured per repository and evaluates the correlation set rather than the full organisation scan. Nothing blocks a merge until you decide it should, and you can start in report-only mode.
What about actions that have no immutable ref?
Some publishers only tag releases. The finding is still recorded with the reference and the publisher, and whether it blocks is your policy. The point is that the mutable reference becomes a recorded decision rather than an unexamined assumption.
Does the platform need write access to our repositories?
No. Read access to the repository and its actions metadata is enough to detect workflow changes and action references. Posting feedback as a check run requires the standard check-run scope and nothing more.
Can you detect secrets being read out of the runner environment?
The detectable event is a secret becoming readable inside a workflow that was also changed, with the ref and the workflow path attached. The platform does not enumerate runner memory, and does not claim to.

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.