CI Secure

Close critical attack vectors in GitHub Actions with /ci-secure

Install the agent skill to check your CI for ten critical attack vectors an outsider could exploit and fix them

MIT licensed. Runs on your machine under your own gh login. No StarSling account, no data sent to StarSling.

how it works

What ci-secure does

Deterministic scanning
The scanner, not the LLM, decides what counts as a finding. It parses your workflow YAML locally with PyYAML and uploads nothing. The optional network calls go to GitHub, under your own gh login.
Agent-powered fixes
Your coding agent explains each finding as a plain-English attacker scenario, then applies the fixes you choose to your working tree for review.

Find the workflows an attacker could hijack, understand exactly how the attack works, and close the vulnerability before it is exploited.

  1. Scan every workflow

    Run /ci-secure inside your repository.

    The scanner reads every file under .github/workflows locally and checks it against the ten supported attack vectors.

  2. Find exploitable paths

    ci-secure reports only vulnerabilities that can give an outsider a path to a concrete compromise.

    That can include executing malicious code with repository privileges, stealing secrets, gaining access to a write token, or poisoning an artifact your repository ships.

  3. See the attacker's path

    Each finding tells you:

    • Which workflow is affected
    • Where the vulnerability begins
    • What input the attacker controls
    • What the attacker could ultimately do

    No rule IDs without context. No unexplained severity labels.

  4. Fix what you choose

    Select the findings you want to close. Each one closes with a focused workflow change, such as a changed trigger, a removed interpolation, a reduced token permission, or a re-pinned action SHA.

    Your coding agent updates the affected workflow files and leaves the changes in your working tree for review. It never commits, pushes, or opens a pull request on its own.

the catalog

Ten critical GitHub Actions attacks

Critical exploit-chain checks only: this is not a comprehensive security audit.

Every vector below is backed by a named public incident or published security research.

  1. Template injection

    Attacker-controlled text, such as a pull request title or branch name, is inserted directly into a shell command and executed by the workflow.

    Seen in the wildSeen in incidents involving nx (opens in new tab), elementary-data (opens in new tab), and Ultralytics (opens in new tab).

  2. Fork code executed with privileges

    A workflow triggered by an untrusted contribution checks out and runs code from an outsider's fork while holding repository privileges.

    Since June 2026, actions/checkout's default refuses fork checkouts on privileged triggers, but a SHA- or patch-pinned checkout never receives that change, other untrusted event types sit outside it, and a manual git fetch bypasses it entirely.

    Seen in the wildDocumented by GitHub Security Lab (opens in new tab) and seen in the Trivy incident (opens in new tab).

  3. Poisoned shared cache

    Attacker-controlled code poisons a shared cache that is later restored and executed by a trusted workflow.

    GitHub made fork-written caches read-only on github.com in June 2026; the path stays open on GitHub Enterprise Server, on third-party cache backends, and for poisoning from a trusted trigger that runs untrusted code.

    Seen in the wildSeen in incidents involving TanStack (opens in new tab) and Ultralytics (opens in new tab).

  4. Impostor action SHA

    A workflow pins an action to a commit that never existed in the canonical repository, allowing the pin to resolve to attacker-controlled code.

    Seen in the wildSeen in the tj-actions incident (opens in new tab) and Chainguard's impostor-commit research (opens in new tab).

  5. Whole-context secrets dump

    A workflow serializes its entire secrets context into logs or environment variables, exposing credentials to anything running in the job.

    Seen in the wildSeen in the tj-actions payload behavior (opens in new tab) disclosed in 2025.

  6. GITHUB_ENV or GITHUB_PATH hijack

    Attacker-controlled input is written into GITHUB_ENV or GITHUB_PATH, changing the environment or executable path for later steps.

    Published researchDocumented by GitHub Security Lab (opens in new tab).

  7. Write token on an untrusted trigger

    A workflow grants write permissions to an event an outsider can trigger, causing attacker-controlled activity to run with repository write access.

    GitHub shipped workflow-trigger policies in June 2026, but they are opt-in and evaluate-mode, so nothing changes on default configuration.

    Seen in the wildSeen in the elementary-data incident (opens in new tab).

  8. Credentials in caches or artifacts

    Private keys or credential files are stored in caches or uploaded artifacts where other jobs, users, or the public may be able to retrieve them.

    Seen in the wildDocumented in analysis of the Trivy cache compromise (opens in new tab).

  9. Unverified curl piped to bash

    A workflow downloads and immediately executes a remote script without verifying it. If the remote host is compromised, the attacker gains execution inside your workflow.

    Seen in the wildSeen in the Codecov breach (opens in new tab).

  10. Dependency install scripts in a privileged job

    A package you depend on is taken over and its install script runs the next time your workflow installs dependencies, inside a job holding secrets or a write token. The attacker never touches your repository; the script executes with the job's credentials before a single test has run.

    Seen in the wildSeen in the s1ngularity postinstall payloads (opens in new tab) in 2025 and the Miasma npm compromise (opens in new tab) in 2026.

FAQ

Frequently asked questions

Is ci-secure a complete security audit?

No.

Critical exploit-chain checks only: this is not a comprehensive security audit.

ci-secure focuses specifically on ten critical GitHub Actions attack vectors that give an outsider a path to a concrete compromise.

Broader CI configuration and best-practice checks belong in /ci-score.

Does the LLM decide what counts as a vulnerability?

No.

The deterministic scanner decides whether a workflow matches one of the ten supported attack vectors. The coding agent explains the finding and applies the fix you choose.

Does any of this reach StarSling?

No.

The scanner reads your workflow YAML locally, nothing is sent to StarSling, and you do not need a StarSling account to run it. The only optional network calls are GitHub lookups, one checking whether a pinned action SHA exists in the canonical repository and one reading a workflow's recent run history to tell you a finding sits in a dormant workflow, and both use your own gh CLI login.

Will it modify my repository?

Only after you choose a finding to fix.

Changes are applied to your working tree for review. ci-secure never commits, pushes, or opens a pull request on its own.

What happens when the scan finds nothing?

The report says zero findings.

It does not add lower-priority observations, inflate the result, or silently pass checks that could not run.

Browse every agent skill
run it

Close the paths attackers could use to hijack your CI

Install the skill, run /ci-secure, and review any critical GitHub Actions vulnerability it finds before choosing what to fix.

then run /ci-secure

MIT licensed. Runs on your machine under your own gh login. No StarSling account, no data sent to StarSling.

Don’t want to run it each time? StarSling’s agents keep reviewing your workflows and open the PRs you review as your CI changes.

Get StarSling