Verified11 commandsAI-assisted

Snyk

.md

Verified against Snyk CLI 1.1299.0, flags verified via `snyk --help` / `snyk test --help` run locally; · official docs

What it is and where it fits#

Snyk is a commercial platform (with a real free tier) that bundles four scanner types behind one CLI and one account: SCA (snyk test — open-source dependency vulnerabilities), SAST (snyk code), container scanning (snyk container), and IaC scanning (snyk iac). The thing that differentiates Snyk's SCA specifically from a purely offline scanner like trivy fs is continuous monitoring (snyk monitor) — it snapshots your dependency tree to snyk.io and keeps alerting on it as new CVEs get published against packages you already shipped, without you needing to re-run a scan. Free tier requires snyk auth; almost every command needs an authenticated account, which is the main practical difference from the fully-offline tools elsewhere in this list (Trivy, Grype, Gitleaks).

How SCA scanning + monitoring fit together#

Diagram

snyk test answers "is this build safe to ship right now"; snyk monitor answers "is anything I've already shipped newly unsafe as of today's CVE feed" — most real pipelines run both, test as a required CI gate and monitor as a post-merge/post-deploy step.

Installation#

npm install -g snyk                          # official, deploys as a binary via npm with graceful degradation
brew install snyk                            # macOS/Linux Homebrew
# or download a standalone binary for your OS/arch from the Snyk CDN (no Node/npm required):
curl -Lo snyk https://static.snyk.io/cli/latest/snyk-linux
chmod +x snyk && sudo mv snyk /usr/local/bin/

snyk --version
snyk auth                                    # opens a browser to authenticate the CLI with your Snyk account
snyk auth --auth-type=token <API_TOKEN>       # non-interactive, for CI (store the token as a secret, never inline)

SCA — open-source dependency scanning#

snyk test                                     # scan the current project's manifest (auto-detected: package.json, go.mod, requirements.txt, ...)
snyk test --all-projects                      # every project/manifest in the working directory, incl. Yarn workspaces
snyk test --severity-threshold=high            # only report high/critical
snyk test --dev                                # include devDependencies too (excluded by default)
snyk test --json > results.json
snyk test --print-deps                          # print the resolved dependency tree before analysis — useful for debugging "why didn't it find X"
snyk monitor                                   # snapshot the current state to snyk.io for continuous alerting (no pass/fail exit code — this is a report, not a gate)

Container image scanning#

snyk container test myapp:latest
snyk container test myapp:latest --file=Dockerfile          # correlate findings back to the Dockerfile line that introduced them
snyk container monitor myapp:latest
snyk container sbom --format=cyclonedx1_5+json myapp:latest  # generate an SBOM for the image

IaC scanning#

snyk iac test                                 # scans Terraform, CloudFormation, Kubernetes manifests, ARM in the current directory
snyk iac test main.tf
snyk iac test --severity-threshold=medium
snyk iac describe                              # detect unmanaged cloud resources (drift) — resources that exist in the cloud but not in IaC source

SAST — Snyk Code#

snyk code test                                # static analysis of first-party source code
snyk code test --severity-threshold=high

SBOM#

snyk sbom --format=cyclonedx1_5+json --org=<org-id> > sbom.json
snyk sbom test --file=sbom.json                # test an existing SBOM document for known vulnerabilities

The .snyk policy file — ignoring accepted risk#

snyk ignore --id=SNYK-JS-LODASH-1040724 --reason="No fix available; usage doesn't hit the vulnerable path" --expiry=2026-12-31

This writes/updates a .snyk file at the project root:

# .snyk
version: v1.5.0
ignore:
  SNYK-JS-LODASH-1040724:
    - '*':
        reason: No fix available; usage doesn't hit the vulnerable path
        expires: 2026-12-31T00:00:00.000Z

The .snyk file applies only to projects at the same path as the file — for a monorepo with multiple manifests, either keep one .snyk per project directory, or point explicitly at a centralized one with --policy-path. Commit it to git: this ensures a scan run through the Snyk UI or an SCM integration respects the exact same accepted-risk rules as a local/CI CLI run, rather than drifting apart.

For IaC specifically, ignore rules can scope to a single file or a single resource path rather than the whole project — see snyk iac test --help for the narrower --ignore-policy shape.

Real-world scenario: gate a PR only on fixable issues#

Reporting every known vulnerability — including ones with no available fix — produces a backlog nobody can act on and trains a team to ignore the tool. Gate the build only on what's actionable:

snyk test --fail-on=upgradable                 # only fail the build on issues with an available fix (upgrade or patch)

Everything else still shows up in the report (and in snyk monitor's ongoing tracking) without blocking the merge — the backlog is visible, but doesn't create a wall nobody can clear.

Real-world scenario: GitHub Actions CI gate#

# .github/workflows/snyk.yml
name: Snyk
on: [pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: snyk/actions/node@master     # language-specific action variants exist (python, golang, docker, iac, ...)
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high --fail-on=upgradable

CI-relevant flags#

snyk test --org=<org-id>                       # scope to a specific Snyk Organization
snyk test --exclude=dir1,file2                  # exclude directory/file names when using --all-projects
snyk test --detection-depth=3                     # limit how many subdirectories --all-projects searches
snyk test --remote-repo-url=https://gitlab.com/org/project   # override the target repo URL shown in the Snyk UI

Sample output shape#

Real snyk test output on a project with findings (exact CVE IDs, counts, and formatting vary by project/version — this shows the shape, not a literal capture):

Testing /path/to/project... ✗ High severity vulnerability found in lodash Description: Prototype Pollution Info: https://security.snyk.io/vuln/SNYK-JS-LODASH-1040724 Introduced through: lodash@4.17.15 Fix: Upgrade to lodash@4.17.21 Organization: my-org Package manager: npm Target file: package.json Open source: no Project name: my-project Docker image: no Licenses: enabled Tested 142 dependencies for known issues, found 1 issue, 1 vulnerable path.

Common pitfalls#

  • Forgetting snyk auth — nearly every command needs an authenticated session; an un-authenticated run fails immediately rather than degrading to a limited offline mode.
  • snyk monitor doesn't gate anything — it's a fire-and-forget snapshot for continuous tracking, not a pass/fail check; using it where you meant snyk test means CI never actually blocks on anything.
  • .snyk file scope — an ignore rule written at the wrong directory level (relative to a monorepo's many manifests) silently doesn't apply where you expect.
  • --all-projects without --detection-depth — on a very large monorepo this can search far more subdirectories than intended and slow the scan substantially.

Exit codes#

0 success, no vulnerabilities found · 1 vulnerabilities found (action needed — this is the CI-gate signal) · 2 scan failed, re-run with -d for debug logs · 3 no supported project detected.

When to reach for something else#

Snyk's SCA overlaps with Trivy's filesystem scan and with npm/pip's own audit commands; its container scanning overlaps with Trivy/Grype; its IaC scanning overlaps with Checkov/tfsec. Snyk's edge is the unified platform and continuous monitoring across all four scan types under one account — a team already fully committed to open-source, offline-only tooling may reasonably prefer Trivy/Grype/Checkov instead and skip Snyk entirely.