Skip to main content
The Caesars

Caligula: Software Supply Chain Security Scanner

Caligula scans software supply chains for known vulnerabilities, malicious packages, compromised AMIs, and IaC image references across 7 ecosystems and 12 manifest formats, integrated natively into Guard.

Caligula introduction card

Modern software is mostly other people's code β€” npm packages, pip wheels, Maven JARs, base images, AMIs. Caligula, open source and integrated into the Praetorian Guard Platform, scans your supply chain for known vulnerabilities, malicious packages, typosquats, hidden binaries, obfuscated payloads, and unpatched cloud images β€” across 7 ecosystems and 12 manifest formats, with zero API keys required.

What Caligula Does For You

Caligula runs scanning modules against your source repositories and AWS images, returning enriched, gateable findings ready for CI:

  • Dependency vulnerability scanning β€” discovers manifest files, extracts every declared dependency, and queries OSV.dev for known CVEs. Findings are enriched with CVSS base score, EPSS exploitation probability, CISA KEV flag, and the earliest fixed version.
  • Malicious package detection β€” eight detection passes including known-malware advisories, typosquatting (homoglyph, combosquat, edit-distance), repository integrity mismatch, compromised maintainer-domain takeover, hidden compiled binaries, code obfuscation, and malicious install-script analysis.
  • AMI vulnerability scanning β€” extracts the installed package list directly from an Amazon Machine Image via the AWS EBS Direct API. No instance launch needed. Matched against the Amazon Linux Advisory (ALAS) feed and enriched with EPSS and KEV. Ubuntu and Debian AMIs are matched against OSV.dev.
  • Infrastructure-as-Code scanning β€” discovers AMI references inside Terraform, CloudFormation, Packer, and plan JSON, peels each AMI, and reports CVEs tagged with the exact file and line of IaC that introduced the vulnerable image.

CLI Subcommands

The Caligula CLI is organized into subcommand groups:

caligula
β”œβ”€β”€ dependencies
β”‚   β”œβ”€β”€ scan <directory>
β”‚   └── advisories
└── machine-images
    β”œβ”€β”€ scan {aws|azure|gcp}
    └── discover-from-iac <directory>

Global flags (--formats, --no-policy, --strict, --baseline, --write-baseline) apply to all subcommands.

Coverage That Matches Real Codebases

Caligula understands the manifests your engineers actually commit:

npm (package-lock.json v1/v2/v3, package.json, overrides), Yarn (v1 + Berry), pnpm (v5 + v6), pip (requirements.txt), Pipenv (Pipfile, Pipfile.lock), pyproject (PEP 621 + Poetry, poetry.lock, uv.lock), Go modules (go.mod with go.sum verification against sum.golang.org), Maven (pom.xml), Gradle (build.gradle, .kts, libs.versions.toml, Groovy ext blocks), NuGet (.csproj, packages.lock.json), RubyGems (Gemfile.lock), Composer (composer.lock), and Amazon Linux RPM (rpm-qa manifests or peeled directly from an AMI).

For Java projects, pass --resolve-transitive=maven or --resolve-transitive=gradle to invoke the project's mvnw/gradlew wrapper and enumerate the full transitive dependency tree.

Enrichment That Tells You What to Fix First

Every vulnerability finding carries the context CI gates need to make a sharp triage decision:

  • CVSS base score and severity β€” computed from the v2/v3/v4 vector, including the full FIRST.org MacroVector interpolation for CVSS v4.
  • EPSS score and percentile β€” the FIRST.org probability the CVE is exploited in the next 30 days.
  • CISA KEV flag β€” whether the CVE appears in the Known Exploited Vulnerabilities catalog.
  • Earliest fixed version β€” so the upgrade decision is one read away.
  • Lockfile and version-range integrity β€” flags missing lockfiles, orphaned lockfiles, node_modules/ without a committed lockfile, and overly permissive version ranges (*, latest, unbounded >=) that defeat reproducible builds.
  • Checksum verification β€” verifies go.sum against sum.golang.org, requirements.txt --hash entries against PyPI, and package-lock.json SRI integrity against the npm registry. Detects checksum-bypass environment variables (GONOSUMCHECK, GOINSECURE, GOFLAGS=-insecure) hiding in .envrc, Dockerfiles, and CI workflows.

Eight-Pass Malicious Package Detection

Beyond known CVEs, Caligula hunts for active supply-chain attacks:

Known malware via OSV.dev MAL-* advisories plus a Praetorian-curated feed for attacks not yet indexed upstream (including advisories such as PRAETORIAN-2025-0001). Typosquatting with three sub-passes — homoglyph normalization (rn→m, 0→o, capital-I to lowercase-l), combosquat suffix/prefix stripping (-js, -cli, node-, py-), and Levenshtein edit distance — all routed through a metadata gate that escalates confidence on recently published packages or those missing README/license, suppresses legitimate variants that share maintainers with the popular target, and suppresses candidates whose own download count exceeds the popular target. Repository integrity mismatch, compromised maintainer domain via RDAP, compiled binaries hidden in node_modules/ or vendor/ (ELF, PE, Mach-O, WebAssembly), code obfuscation (eval-with-encoded-args, base64+zlib+exec chains, hex-XOR loops in JavaScript and Python), and install-script analysis (npm lifecycle hooks piping curl-to-shell, Python setup.py with encoded execution, __init__.py credential exfiltration).

Direct Package Advisory Lookup

Use caligula dependencies advisories to query a specific package and version (or version range) without scanning a directory:

caligula dependencies advisories \
  --ecosystem npm --package lodash --version 4.17.20

Results include CVSS, EPSS, KEV status, and affected version ranges from OSV.dev, ALAS, and the Praetorian curated feed. Use --check cve or --check malware to restrict the source. Pass --formats json for machine-readable output.

AMI Scanning Without Launching the AMI

Caligula peels Amazon Machine Images directly through the AWS EBS Direct API β€” downloads only the snapshot blocks it needs, parses the partition table and XFS/ext4 filesystem in pure Go, reads the RPM database (SQLite for AL2023, BDB for AL2), and matches packages against the ALAS feed. Ubuntu and Debian AMIs are extracted via /var/lib/dpkg/status and matched against OSV.dev.

No instance launch. No SSH. No rpm -qa handoff from a customer. Caligula classifies every AMI it touches and surfaces operational coverage gaps as typed findings β€” Marketplace AMIs, instance-store images, KMS-denied snapshots, oversized volumes, deregistered AMIs β€” so a clean report is genuinely clean and a peel failure is never silent.

Provide an AMI ID directly or let Caligula expand an Image Builder build ARN to its output AMIs:

caligula machine-images scan aws --ami-id ami-0abcdef1234567890 --aws-region us-east-1
caligula machine-images scan aws --image-builder-build-arn arn:aws:imagebuilder:us-east-1:123456789012:image/my-pipeline/1.0.0/1

The required IAM permissions are ec2:DescribeImages, ec2:DescribeSnapshots, ebs:ListSnapshotBlocks, ebs:GetSnapshotBlock, and imagebuilder:GetImage. Customer-managed encrypted snapshots additionally require kms:Decrypt and kms:DescribeKey on the relevant KMS key. See docs/iam.md for full least-privilege policies and authentication options (environment variables, instance profile, IRSA, OIDC, and more).

IaC Scanning That Points to the Line

Caligula discovers AMI references in your Terraform, CloudFormation, Packer, and plan JSON, peels each one, and emits CVE findings stamped with the exact source file and line that introduced the vulnerable image. A KEV-tagged finding goes from "your fleet has a problem" to "edit terraform/baseline/main.tf:47" in one click.

Static-mode parsing handles literals, variables (including tfvars overrides and Groovy ext blocks), mappings, and parameter defaults. Opt into --resolve-dynamic to live-resolve data "aws_ami" blocks, SSM parameters, and Packer source filters via the AWS SDK.

Cross-region pinning is automatic: Terraform provider blocks and aliases, Packer source region attributes, and the --aws-region fallback ensure each AMI is looked up in the region where it lives.

Use --no-peel for IaC discovery only (no AWS calls), or --kev-only-gate to fail the build only on actively-exploited CVEs.

Baseline Differential Scanning

Use --write-baseline to capture the current finding set, then --baseline on subsequent runs to suppress previously known findings and surface only new ones:

# First run: capture baseline
caligula dependencies scan --write-baseline baseline.json /path/to/repo

# Subsequent runs: suppress known findings
caligula dependencies scan --baseline baseline.json /path/to/repo

Suppressed findings are preserved in JSON output under ignored_findings for audit. The baseline file is JSON, committable alongside your code, and version-controlled. Policy filtering (.caligula.yaml) runs before the baseline is written, so accepted findings are never captured into the baseline.

CI-Ready Output

Caligula writes whichever format your pipeline consumes:

  • Table to stdout β€” color-coded severity for human review.
  • SARIF 2.1.0 for GitHub Code Scanning β€” findings appear inline on pull requests.
  • JSON β€” every field, including ignored findings preserved for audit.
  • HTML β€” self-contained interactive report with severity filter, full-text search, and sortable columns.
  • CycloneDX v1.6 SBOM β€” every scanned package as a component with its purl, every finding as a vulnerability with CVSS rating and upgrade recommendation.

Exit code 0 means clean, 1 means findings, 2 means scan errors (with --strict). A --kev-only-gate flag lets you fail builds only on actively-exploited CVEs.

Policy That Lives With Your Code

A .caligula.yaml file in the repository tunes scan behavior with versioned, auditable rules: ignore an accepted CVE with a mandatory reason and expiry date, allowlist a legitimate "typosquat" (e.g. flask-login for flask), set a minimum severity threshold, skip IaC paths, or pin kev_only_gate: true for production branches. Suppressed findings are preserved in JSON output for compliance review but excluded from exit codes and SARIF.

version: 1
ignore:
  - id: CVE-2021-44228
    reason: "Mitigated by WAF rule WAF-1234"
    expires: "2025-12-31"
min_severity: medium
iac:
  skip_paths:
    - terraform/legacy/*
  kev_only_gate: true

Zero API Keys, Free Forever

Every data source Caligula reads is free and public β€” OSV.dev, Amazon Linux ALAS, FIRST.org EPSS, CISA KEV, sum.golang.org, the npm and PyPI registries, IANA RDAP, and GitHub's REST API. There are no usage tiers, no rate-limited trial keys, and no vendor lock-in. Cached responses live in ~/.caligula/cache/ with sensible TTLs so repeat scans complete in milliseconds.

Native to Guard β€” Zero Setup Required

Caligula runs natively inside the Praetorian Guard Platform, scanning every repository and AWS image Guard has access to. The more integrations you connect β€” source code managers, AWS accounts, Image Builder pipelines β€” the more ground Caligula covers. Findings surface alongside your other risks, fully integrated into your existing remediation workflows.

Guard triggers Caligula automatically via two paths:

AI-assisted (Ask Marcus): From any repository or AMI asset in Guard, open the Ask Marcus panel and request a supply chain security assessment. The Aurelius assistant matches the asset to the Caligula capability and initiates a scan.

Direct capability invocation: From the Capabilities drawer on any Repository or AWS asset, select the Caligula capability, configure parameters (module, minimum severity, KEV-only gate), select target assets, and run. Findings appear in the asset's risk panel.

Open Source β€” Inspect Every Check, Contribute Your Own

Caligula is fully open source at github.com/praetorian-inc/caligula. Inspect every detection rule, audit the AMI peel pipeline, contribute a custom advisory for an attack OSV hasn't indexed yet. The same code Praetorian's offensive operators run during engagements is the code that runs inside Guard β€” and the code you can run yourself today.

Get Started

Guard Platform customers already have Caligula working for them. To run it standalone:

git clone https://github.com/praetorian-inc/caligula
cd caligula
go build -o caligula .
./caligula dependencies scan /path/to/your/repo

Or to gate a CI pipeline on actively-exploited CVEs only:

./caligula dependencies scan --kev-only-gate --formats sarif /path/to/repo

Reach out to your Praetorian engagement team to discuss how Caligula-powered supply chain scanning fits into your security program.