CLI reference

All commands are Composer plugin commands and accept Composer's global options as well (-v, -q, --no-ansi, -d/--working-dir, --no-plugins, and so on). composer <command> --help prints the same information in the terminal.

composer remediate

Find the least invasive Composer-verified upgrade that removes each known vulnerability from composer.lock

Reads composer.json and composer.lock, matches the locked packages against security advisories, and for every finding tries a series of composer update commands in a dry-run, from least to most invasive. Only commands whose resulting lock file no longer contains the vulnerability are recommended. Nothing in the project is modified.

Exit codes: 0 no vulnerabilities, 1 vulnerabilities with a verified remediation, 2 at least one vulnerability without a verified remediation (and no tool failure), 3 error (also when a solver error prevented the search from completing), 4 advisory data unavailable (also when the source could not read records about locked packages and --accept-coverage-gaps was not given), 5 package metadata could not be fetched while solving.

Advisories come from an advisory database kept at --database-path (default: Composer's cache directory). On every run the file is checked against the published database it comes from (--database-location, default: this project's release): a copy with the same sha256 or dataset hash, or a newer local build, is used; a missing or stale copy is downloaded (or rebuilt with --rebuild-database); when the source cannot be reached the copy is used and the report says how old it is. Without any usable database the configured repositories are asked, as composer audit does, and the report says so. --no-database chooses that directly.

Running as composer remediate means Composer has already activated the project's other allowed plugins before this command starts. The composer-remediate binary shipped with the package runs the same command with plugins and scripts disabled from the first instruction.

Option Value Description
--format, -f required, default text Format printed to standard output: text, html, json, sarif, cyclonedx, gitlab or none
--output, -o repeatable Also write a report file; format inferred from the name (.html, .json, .sarif, .cdx.json, gl-dependency-scanning-report.json, .txt) or given as sarif:path. Repeatable.
--fail-on required Only findings at or above this severity (low, medium, high, critical) affect the exit code; findings of unknown severity always count
--baseline required Baseline file of accepted findings; findings listed there are reported but do not affect the exit code
--update-baseline flag Write every finding of this run to the --baseline file (accept the current state, then tighten over time)
--min-release-age required Never recommend a release published fewer than this many days ago, or without a known release date (supply-chain cooldown)
--no-dev flag Ignore vulnerabilities in require-dev packages
--offline flag Refuse all network access; needs a warm Composer cache plus an advisory database already at its path, or --advisories-file (sets COMPOSER_DISABLE_NETWORK=1)
--ignore, -i repeatable Advisory id or CVE to ignore (repeatable); audit-scoped entries of config.audit.ignore and config.policy.advisories are honoured as well
--allow-direct-require flag Also consider adding a transitive package as a direct requirement to force a fixed version
--advisories-file required Read advisories from a JSON file in the Packagist API shape (or composer audit --format=json output) instead of the configured repositories
--database-location required Where the advisory database comes from: https URL(s) of a published database, comma-separated and tried in order (default: the database this project publishes); composer to ask the configured repositories instead; or a local file to read as it is. Also REMEDIATE_DATABASE or extra.remediate.database
--database-path required The file the advisory database is kept in and read from (default: COMPOSER_CACHE_DIR/remediate/advisories.sqlite); also REMEDIATE_DATABASE_PATH or extra.remediate.database_path. Cache it between CI runs
--database-max-age required When the database cannot be confirmed current (source unreachable, --offline), fail with exit 4 instead of warning if the copy is older than this many hours (or 2d, 36h); also REMEDIATE_DATABASE_MAX_AGE or extra.remediate.database_max_age
--no-database flag Ask the configured repositories for advisories, as composer audit does, instead of using an advisory database (same as --database-location=composer)
--rebuild-database flag When the database at its path is missing or not current, build it from the sources (Packagist, OSV, FriendsOfPHP, with EPSS and KEV data) instead of downloading it
--database-sha256 required Expected sha256 of the advisory database (hex); a downloaded or cached copy that differs is refused. The trust anchor for a URL you do not publish yourself
--allow-unverified-database flag Accept a database URL without a published <url>.sha256 sidecar and without --database-sha256 (refused otherwise); the report says the download was not verified
--accept-coverage-gaps flag Exit 0 for a lock without findings even when the advisory source could not read records about locked packages (otherwise exit 4); the gaps stay in the report
--max-candidates required, default 10 Maximum number of candidate commands to try per finding
--solve-budget required, default 60 Maximum number of solver runs per finding, all search phases included (candidates, conflict expansion, parent descent, simplification)
--solver required, default auto How candidates are verified: auto (in-process, falling back to a composer update subprocess when the in-process route errors), in-process, or subprocess
--ignore-platform-req repeatable Ignore a specific platform requirement (php & ext- packages) when validating candidates; the flag is repeated in the recommended command
--ignore-platform-reqs flag Ignore all platform requirements when validating candidates; the flag is repeated in the recommended command

composer remediate:db-build

Aliases: remediate-db-build

Build a local advisory database (SQLite) from live sources: Packagist, OSV and FriendsOfPHP

Pulls every advisory for the Packagist ecosystem from the selected sources (plus any --include files with private advisories), normalises the version ranges to Composer constraints, merges records that share an identifier (CVE, GHSA, PKSA, FriendsOfPHP file), keeps every source's range and flags disagreements, and writes a single SQLite file.

Every CVE in the database is enriched with its EPSS exploit probability and its CISA KEV listing when present (--enrich); reports order findings by that urgency. A feed that cannot be fetched is recorded in the database's metadata and the build continues without it.

Written to the path composer remediate reads by default, so the next run uses it; a build with no options reproduces the database this project publishes. --if-stale first checks the existing file against the published database (same sha256 or dataset hash, or a newer local build) and skips the build when it is current, which suits a CI cache. The file is portable: publish it on a web server or as a release asset with a .sha256 sidecar (or a latest.json) and point other machines at the URL with --database-location.

Option Value Description
--output, -o required Where to write the database (default: the configured path, see --database-path of remediate; COMPOSER_CACHE_DIR/remediate/advisories.sqlite unless configured)
--if-stale flag Build only when the database at the output path is missing or not current against the published one (REMEDIATE_DATABASE or extra.remediate.database, default: this project's release); otherwise report it as current and exit 0
--source, -s repeatable Source to include: packagist, osv, friendsofphp (repeatable; default all)
--friendsofphp-path required Local checkout of FriendsOfPHP/security-advisories to read instead of downloading
--include repeatable Additional JSON file in the Packagist API shape with private or organisational advisories (repeatable)
--enrich repeatable Exploit data to attach to the CVEs: epss (FIRST exploit probability), kev (CISA Known Exploited Vulnerabilities), or none (repeatable; default both)
--epss-file required Local copy of the EPSS scores CSV (plain or .gz) to read instead of downloading
--kev-file required Local copy of the CISA KEV catalogue JSON to read instead of downloading

composer remediate:db-status

Aliases: remediate-db-status

Show where the advisory database comes from and what it contains

Option Value Description
--database-location required Where the database comes from: https URL(s) tried in order (default: the database this project publishes), composer for none, or a local file; also REMEDIATE_DATABASE or extra.remediate.database
--database-path required The file the database is kept in (default: COMPOSER_CACHE_DIR/remediate/advisories.sqlite); also REMEDIATE_DATABASE_PATH or extra.remediate.database_path
--database-max-age required Fail when the copy cannot be confirmed current and is older than this many hours (or 2d, 36h); also REMEDIATE_DATABASE_MAX_AGE
--offline flag Do not contact the source; report on the copy at the path as it is
--database-sha256 required Expected sha256 of the database (hex); a downloaded or cached copy that differs is refused
--allow-unverified-database flag Accept a database URL without a published <url>.sha256 sidecar and without --database-sha256

Exit codes

Code Meaning
0 No known vulnerabilities in the locked dependencies
1 Vulnerabilities found and a verified remediation exists for every one
2 At least one vulnerability has no verified remediation
3 Tool or configuration error (no lock file, unknown option, unwritable output)
4 Advisory data could not be obtained (network, missing or invalid database or snapshot); also used by remediate:db-build when a source fails
5 Package metadata could not be fetched during solving (network), so no candidate could be verified

Environment variables

Variable Effect
REMEDIATE_DATABASE Path or URL of the advisory database, used when --database-location is not given
COMPOSER_DISABLE_NETWORK Set to 1 by --offline; may also be set by hand to make every Composer call refuse the network
COMPOSER_CACHE_DIR, COMPOSER_HOME Composer's own; the advisory database default output and URL downloads live under <cache-dir>/remediate/

composer.json keys

Key Effect
extra.remediate.database Default advisory database location for this project (path or URL), lowest precedence after the option and the environment variable
config.audit.ignore Advisory ids (list, or map of id to reason) that are ignored, as composer audit does (Composer 2.x)
config.policy.advisories.ignore, config.policy.advisories.ignore-id Same, in the policy block introduced by Composer 2.10
config.platform Honoured by candidate solves exactly as by composer update; determines whether a fix requiring a newer PHP is reachable

Report formats

--format selects what goes to standard output (text by default, or html, json, sarif, cyclonedx, gitlab, none). --output=<file> writes a report file, format inferred from the name (.html, .json, .sarif, .cdx.json, gl-dependency-scanning-report.json, .txt) or given as a prefix (json:path); it may be repeated. See How it works for the formats and schema/report.schema.json for the JSON Schema.