DEV Community

depmedicdev-byte
depmedicdev-byte

Posted on • Originally published at depmedicdev-byte.github.io

ci-doctor vs zizmor: when to use which (honest take from one of the maintainers)

I maintain ci-doctor. People keep asking how it stacks up against zizmor, William Woodruff's Rust-based GitHub Actions security analyzer. So here's the honest version, not the marketing version.

tl;dr — If your priority is supply-chain security and you only care about that, run zizmor first. If you also want cost waste catches and reliability rules in the same pass, add ci-doctor. Both have SARIF output, both are MIT.

Where zizmor wins

  • Deeper template-injection analysis. Traces user-controlled context (github.event.issue.title, github.event.pull_request.head.ref) into run: blocks across step boundaries.
  • Sub-rule precision on pull_request_target + checkout patterns. Knows the difference between checking out a PR head, checking out the base, and the new "trusted" mode you can opt into.
  • Audits self-hosted runner labels, impostor commits, ref confusion, cache poisoning. ci-doctor does not have any of these.
  • 23+ pure security rules vs ci-doctor's 6 security rules.
  • Native Rust binary, no Node runtime needed. Single download, fast cold start.
  • Maintained by a well-known supply-chain security researcher who's been doing this for years.

Where ci-doctor wins

  • Cost rules zizmor does not have. missing-concurrency, missing-cache, expensive-runner, cron-storm, wide-paths, service-no-healthcheck. These are real money on free-tier and paid-tier alike.
  • Reliability rules zizmor does not have. missing-timeout-minutes, flaky-retries, legacy-actions-version.
  • Auto-fix mode. npx ci-doctor --fix rewrites four safe categories in place. zizmor is read-only.
  • Pairs with gha-budget for $-denominated cost numbers per workflow.
  • Zero install via npx ci-doctor — no compile, no PATH wiring.
  • Same engine ports to GitLab, Bitbucket, Azure, CircleCI. One mental model across CIs.

Rule overlap, side by side

Concern zizmor ci-doctor
Pin uses: to SHAs yes yes
Template injection from user input deep basic
pull_request_target + checkout yes (sub-rule precise) yes
Container image not pinned to digest no yes
Self-hosted runner label spoofing yes no
Cache poisoning vectors yes no
Service container missing healthcheck no yes
Missing concurrency: (cost) no yes
Missing timeout-minutes: (cost+reliability) no yes
Missing language/dep cache (cost) no yes
Expensive runner (cost) no yes
Auto-fix mode no yes (--fix)
SARIF output yes yes
Other CIs (GitLab, Bitbucket, Azure, CircleCI) no (GHA-only) yes

Run them side by side

This is what I recommend for any team that takes both security and cost seriously:

name: ci-audit
on: pull_request
permissions:
  contents: read
  security-events: write
jobs:
  zizmor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install zizmor
      - run: zizmor --format sarif . > zizmor.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: zizmor.sarif, category: zizmor }
  ci-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: depmedicdev-byte/ci-doctor-action@v1
Enter fullscreen mode Exit fullscreen mode

Both reports land in the same Security tab under different categories. No conflict.

What about actionlint, super-linter, MegaLinter, woodpecker?

  • Woodpecker is a CI system, not a workflow linter, so it isn't in the same category.
  • actionlint is the gold standard for syntactic and shell-safety checks. ci-doctor is cost and reliability first. They're complementary - I run both on my own repos. Honest comparison: /compare/ci-doctor-vs-actionlint.html.
  • super-linter and MegaLinter are heavyweight wrappers that bundle 50+ language linters and incidentally include actionlint. Different problem entirely.

Why I wrote this

Because every "X vs Y" comparison written by one of the maintainers is suspicious by default, and I'd rather you have the honest version than discover the trade-offs after committing one to your CI.

If anything here is wrong or outdated, open an issue and I'll fix it. We do not pay for placement and we do not accept paid placement.

Full version with the table styled and link colors fixed: /compare/ci-doctor-vs-zizmor.html.

Top comments (0)