Containers Command Reference

The containers command runs a focused scan that evaluates only container-security Rego rules (rules with kind: oci) against Dockerfile and Containerfile manifests. It is equivalent to running:

vulnetix scan --enable-containers --no-sast --no-sca --no-secrets --no-iac --no-licenses

Package vulnerability analysis, general SAST rules, license analysis, secret detection, and IaC analysis are all disabled. Only rules that analyse container build files run.

The command also runs a local ELF binary analysis pass and can inspect unpacked container root filesystems or saved image/rootfs tar archives. Rootfs/archive inspection reads installed OS package databases such as dpkg, apk, and pacman and scans discovered ELF binaries without pulling images or requiring a Docker/Podman daemon.

Binaries are also read for the packages compiled into them — Go build info, Rust cargo auditable crate lists and JVM archive coordinates — and, where a package database is present, each binary is attributed to the package that installed it. Discovered packages are printed and merged into .vulnetix/sbom.cdx.json (existing components, findings and VEX statements are left in place). Disable this pass with --no-binary-package-analysis; the ELF weakness scan still runs. See Binary package discovery for what each format yields.

The binary inventory

When you are authenticated, the ELF pass uploads what it found: for every binary, its hashes, ELF header, hardening weaknesses (no PIE, no RELRO, no stack canary, setuid), capabilities, extracted strings and EXIF, the CIRCL hashlookup correlation and the local malware-corpus verdict. That is the record an SBOM cannot give you — an unpackaged binary nobody declared is in no manifest, but it is on disk.

It attaches to the same snapshot as the container scan that produced it, so one vulnetix containers run is one entry in the console rather than two. A standalone --container-rootfs inspection with no container scan around it gets a snapshot of its own.

The inventory is a forensic record, not a verdict:

  • Vulnerabilities come from the packages the binaries are read for — Go build info, cargo-auditable crate lists, JVM coordinates — which travel as real purls in the SBOM and are matched there. A CIRCL package name with no ecosystem to qualify it is not matched against advisories; string-matching “openssl” across every source is how a scanner starts reporting things that are not true.
  • Malware raises its finding through malscan, which owns the triage and VEX records. A binary the corpus flags here is marked on its inventory row and counted in the command’s output.

Credentials are optional. When no credentials are configured the community fallback is used automatically.

Usage

vulnetix containers [flags]

Flags

FlagTypeDefaultDescription
--pathstring.Directory to scan
--depthint3Maximum recursion depth for file discovery
--excludestringArray-Exclude paths matching glob pattern (repeatable)
-o, --outputstringArray-Output target: json-sarif for stdout; .sarif file path for file output
--no-progressboolfalseSuppress the progress bar
--severitystring-Exit 1 if any finding meets or exceeds: low, medium, high, critical
--results-onlyboolfalseOnly output when findings exist
--dry-runboolfalseReport what this command would scan — rule kinds, external rule packs, discovered files — then replay stored results. Zero API calls.
--list-default-rulesboolfalsePrint the built-in rule table and exit
--snippet-contextint-1Source lines captured around each SARIF finding (-1 = dynamic, 0 disables)
--containers-include-ignoredboolfalseInclude files matched by .gitignore (default: gitignored paths are skipped)
--container-rootfsstringArray-Inspect a container root filesystem directory for installed packages and ELF binaries
--container-archivestringArray-Inspect a Docker/OCI/rootfs tar archive for installed packages and ELF binaries
--no-binary-package-analysisboolfalseSkip package discovery from compiled binaries (Go build info, cargo-auditable, JVM archives); the ELF weakness scan still runs

Detected File Types

The containers command scans files identified as container, Kubernetes and Helm manifests, extracting the referenced images as pkg:oci/… components (each annotated with its registry type and a private-registry flag):

FilenameLanguageWhat is extracted
Dockerfile / Containerfile / *.dockerfiledockerFROM base images + RUN-installed OS packages
compose.yaml / docker-compose.ymldockerservice image: references
*.yaml with apiVersion + kindkubernetespod-template images (Pod / Deployment / StatefulSet / DaemonSet / Job / CronJob, incl. init & ephemeral containers)
Chart.yamlhelmchart dependencies (pkg:helm/…) + sibling values.yaml images

What Gets Detected

Container security rules check for common Dockerfile misconfigurations:

Rule IDSeverityName
VNX-DOCKER-001MediumMissing USER directive (running as root)
VNX-DOCKER-002MediumFROM with :latest tag (unpinned base image)
VNX-DOCKER-003MediumMissing HEALTHCHECK instruction
VNX-DOCKER-004MediumPackage manager cache not cleared in same layer
VNX-DOCKER-005HighSecrets or credentials in ENV instruction
VNX-DOCKER-006MediumPrivileged port exposure (< 1024)
VNX-DOCKER-007MediumADD instruction used instead of COPY
VNX-DOCKER-008MediumMultiple RUN instructions that could be combined

See the Docker rules section for full details.

Examples

# Container scan of the current directory
vulnetix containers

# Scan a specific directory
vulnetix containers --path /path/to/project

# Break the build on any container finding
vulnetix containers --severity low

# Emit SARIF JSON to stdout
vulnetix containers --output json-sarif

# Write SARIF to a file
vulnetix containers --output containers.sarif

# Silent when no issues found
vulnetix containers --results-only

# Inspect an unpacked container rootfs
vulnetix containers --container-rootfs ./rootfs

# Inspect a saved image tar without using Docker
vulnetix containers --container-archive ./image.tar

Output Files

PathDescription
.vulnetix/containers.sarifSARIF 2.1.0 report from container analysis. Unlike secrets and iac, which write sast.sarif, a container-only scan gets its own file
.vulnetix/sbom.cdx.jsonCycloneDX SBOM for the packages found in the image or its base images
.vulnetix/memory.yamlScan state record (timestamp, finding counts, git context)

Exit Codes

CodeMeaning
0Scan completed successfully (no threshold breach)
1A gate was breached (--severity), or a fatal error occurred

Known false negatives

Detection is deliberately conservative — a missed detection is preferred over a wrong one. Not detected, by design:

  • Images mirrored to private or organisation-local registries when matching official-image heuristics (base-image analysis follows the reference as written).
  • Build-arg ($VAR) and Helm-templated ({{ ... }}) image references — placeholders are dropped, never guessed.
  • Packages installed by scripts fetched at build time (curl | sh) rather than by a recognised package manager invocation.
  • A malformed image digest is dropped rather than reported as a version — it never becomes a fabricated value.

Absence of a finding is not verified absence of container risk.