Two separate rule sets, not one
This is the detail most comparisons skip: Dockerfile hygiene and CI/CD pipeline security are two distinct rule categories with different default states. Getting this wrong means either missing coverage you assumed you had, or being surprised a scan didn't report something.
Dockerfile hygiene — on by default
General Dockerfile rules live under the SECURITY category, enabled in every scan with no configuration:
| Rule | Severity | What it catches |
|---|---|---|
| dockerfile_root_user | HIGH | No USER directive — the container runs as root by default. |
| dockerfile_copy_all | MEDIUM | COPY . . pulls the entire build context, including .env, credentials, SSH keys, into the image. |
| dockerfile_unpinned_base | MEDIUM | Base image not pinned to a specific version. |
CI/CD pipeline rules — opt-in, off by default
This is the part worth being precise about: the 38 rules that inspect .github/workflows/*.yml and .gitlab-ci.yml content — expression injection, permission scoping, unpinned actions, and the rule below — are grouped under a separate CICD category that is disabled by default, the same way dependency scanning needs --with-deps. There is no CLI flag for it; it is a config setting.
Enable it in audit.config.json:
"categories": {
"cicd": { "enabled": true, "weight": 2 }
}
Set this before the first scan of a project (or clear the rules cache with --no-cache once if toggling it on an already-scanned project) — then run normally.
| Rule | Severity | What it catches |
|---|---|---|
| pull_request_target_checkout | HIGH | pull_request_target combined with a checkout of the fork's head — lets a forked PR run code with write access and secrets. |
| unpinned_action_version | MEDIUM | An action referenced by branch or tag (@main, @v4) instead of a full commit SHA. |
| gha_missing_permissions | LOW | Workflow has no explicit permissions: block, defaulting to broader access than needed. |
| docker_latest_tag | LOW | An image: key in CI YAML pinned to :latest — note: this matches the YAML image:/from: key, not a Dockerfile's FROM line (that's a different, Dockerfile-language rule not currently included). |
| workflow_not_in_codeowners | LOW | Workflow files not covered by a CODEOWNERS entry, so changes to CI logic don't require a specific reviewer. |
38 rules total in this category — the table above is a sample, not the full list.
One real example, start to finish
on: pull_request_target
jobs:
build:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
on: pull_request
jobs:
build:
steps:
- uses: actions/checkout@v4
The fix here is not a parameter tweak — it's switching event triggers. pull_request_target runs with the base repo's permissions and secrets even for forked PRs; pull_request does not. If privileged operations are genuinely needed after review, the rule's own guidance is to split them into a separate workflow_run job instead of adding a checkout step to the pull_request_target job.
Frequently asked questions
Why is CI/CD scanning opt-in instead of always on?
The same reason dependency scanning needs --with-deps: not every project has a .github/workflows or .gitlab-ci.yml to begin with, and scanning YAML/pipeline files by default on every project would report zero findings (and cost scan time) for the ones that don't use CI/CD at all. Opt-in keeps the default scan focused on application source code.
Does docker_latest_tag catch a Dockerfile's FROM line?
No — its pattern matches a YAML image: or from: key (the syntax used inside .gitlab-ci.yml job definitions), not a Dockerfile's FROM node:latest line, which has no colon after the instruction. This is a real, verified distinction, not a caveat added for effect — the two syntaxes are different enough that one pattern does not cover both.
Does enabling CICD also scan Dockerfiles differently?
No — Dockerfile hygiene rules (root user, COPY . ., unpinned base image) are in the always-on SECURITY category regardless of the CICD setting. Enabling CICD only adds the pipeline-YAML-specific rules on top.
Is this the same detection as GitHub's own workflow linting?
No — GitHub's own tooling checks workflow syntax validity. These rules check for specific, known-dangerous patterns (privilege escalation via pull_request_target, supply-chain risk from unpinned actions) that a syntactically valid workflow can still contain.
See it on a real pipeline
Open the live demo report — no install, no signup — or enable the CICD category on your own project and scan it.
Open the live report See the CLI reference