Every command
Every command and every option, rendered from the scanner's own argument parser, so nothing here can name a flag that does not exist. cordon-scanner help <command> prints the same for one command at a terminal.
0 clean nothing met the failure policy 1 findings something did: the build should stop 2 scanner error a bug in Cordon; please report it 3 config error the invocation or configuration is wrong 4 incomplete the scan could not read everything (with --fail-on-incomplete)
scan: scan a directory, file or archiveclone: clone, scanned before checkoutpull: pull, scanned before the mergeinventory: what the repository is, and whydeps: dependency graph and findingsreview: what a dependency update addssbom: CycloneDX or SPDX bill of materialsreport: re-render a saved JSON result
Scan a directory, file or archive.
┌────────────────────────────────────────────────────────────────────────────┐ │ target path to scan (default: .), or a package URL such │ │ as pkg:npm/[email protected] (npm, pypi, cargo, gem, │ │ nuget; needs --online) │ │ --host read TARGET as the root of an installed system │ │ (default /): its OS packages and the language │ │ packages installed outside any project, matched │ │ for known vulnerabilities and malicious releases │ │ (OS packages with --online). Files are not │ │ content-scanned │ │ --home DIR with --host, also read this user's own installs │ │ (pipx, ~/.local, ~/go/bin, cargo install) │ │ --history also read every blob in git history that is no │ │ longer in the tree, for secrets │ │ --verify-secrets ask each found credential's own issuer whether │ │ it still works (needs --online) │ │ --include GLOB restrict to matching paths (repeatable) │ │ --exclude GLOB skip matching paths (repeatable) │ │ --staged scan the content staged in git, not the working │ │ tree (for pre-commit hooks) │ │ --tracked scan only files git tracks, skipping build │ │ output and ignored paths │ │ --git-diff REF scan only files that differ from REF │ │ --detector ID run only these detectors (repeatable) │ │ --no-detector ID disable a detector (organisation policy may │ │ forbid this) │ │ --rules PATH additional rule pack (repeatable) │ │ --advisories PATH advisory database to use instead of the bundled │ │ one, as JSON. How an air-gapped site stays │ │ current without network access. │ │ --severity LEVEL report at or above: │ │ info|low|medium|high|critical │ │ --confidence LEVEL report at or above: low|medium|high|confirmed │ │ --fail-on LEVEL fail the build at or above this severity │ │ --fail-on-incomplete treat a degraded scan as a failure │ │ --baseline PATH treat findings recorded in this file as already- │ │ known │ │ --vex PATH an OpenVEX or CycloneDX VEX document │ │ (repeatable): a vulnerability a statement rules │ │ out (not_affected, fixed) is marked suppressed │ │ with its justification │ │ --config PATH repository configuration file │ │ --policy PATH organisation policy file │ │ --format, -f FMT[:PATH] text|json|sarif|junit|markdown|github. │ │ Repeatable. Append :PATH to write that format to │ │ a file, for example --format sarif:cordon.sarif │ │ --output, -o PATH write to a file (only valid with a single │ │ --format) │ │ --evidence MODE none|masked|hash_only (default: masked). The │ │ stricter of this and each rule's own policy │ │ wins, so `none` only takes effect for rules that │ │ permit it -- no shipped rule does. │ │ --timeout SECONDS total wall-clock budget │ │ --no-cache ignore and do not write the incremental cache │ │ --cache-dir PATH where to keep the incremental cache │ │ --jobs, -j N worker processes (0 or unset means automatic) │ │ --offline forbid all network access, including the signed │ │ intel feed (air-gapped use; CORDON_OFFLINE=1 │ │ does the same). The intel's age is still │ │ reported │ │ --online permit the detectors that query a package │ │ registry (npm and pypi only; other ecosystems │ │ are reported as unasked). Off by default; an │ │ organisation policy forbidding network access │ │ still wins, and a config found inside the scan │ │ target can never set it │ │ --compare-with PATH an earlier release of the same package; report │ │ what this one adds -- a new install hook, new │ │ network or execution capability, new obfuscation │ │ or binaries. With --online and a published npm │ │ or PyPI artefact, the previous release is │ │ fetched from the registry instead │ │ --allow-network permit the one network operation there is: │ │ fetching a --policy URL, which must carry a │ │ #sha256= digest. Never used for scanning │ │ --reachability annotate vulnerability findings with import │ │ reachability: a vuln in a transitive dependency │ │ no first-party code imports is lowered and │ │ tagged (never dropped). Reads every source file │ │ to collect imports │ │ --notify CHANNELS when the gate fails, post one message to each │ │ channel: webhook, slack, teams (comma- │ │ separated). URLs come only from │ │ CORDON_NOTIFY_WEBHOOK, CORDON_NOTIFY_SLACK and │ │ CORDON_NOTIFY_TEAMS; the webhook is signed with │ │ CORDON_NOTIFY_WEBHOOK_SECRET. A failed delivery │ │ never changes the exit code │ │ --judge MODEL also have a language model judge agent-facing │ │ text (instruction files, skills, MCP tool │ │ descriptions, hook commands): cordon-cloud │ │ (recommended; `cordon-scanner login`), │ │ anthropic[:<model>], openai:<model>, or │ │ ollama:<model> to keep everything on this │ │ machine. Off by default; only agent-facing text │ │ is sent, and the report says whether it ran │ │ (env: CORDON_JUDGE) │ │ --judge-blocks report a malicious verdict from --judge at HIGH, │ │ inside the default gate (default: it warns) │ │ --judge-max-calls N the most model calls --judge may make in one │ │ scan (default 200) │ │ --registry-token URL=VARIABLE │ │ with --online, ask a private registry about what │ │ was resolved from it, presenting the token held │ │ in the environment variable named (repeatable; │ │ never the token itself). Never set from a │ │ repository's configuration (env: │ │ CORDON_REGISTRY_TOKENS) │ │ --yara RULES also match every file against a YARA rules file │ │ (needs the yara-python module). Off by default; │ │ never set from a repository's own configuration │ │ (env: CORDON_YARA) │ │ --clamav SOCKET also hand each file to a local ClamAV daemon: a │ │ Unix socket path, or tcp://127.0.0.1:3310. Off │ │ by default; the report says whether it ran. │ │ Never set from a repository's own configuration │ │ (env: CORDON_CLAMAV) │ │ --upload send the results to Cordon Cloud after the scan │ │ (K2: an in-toto statement over the JSON results, │ │ signed keylessly with the CI identity when │ │ sigstore is installed). Needs `cordon-scanner │ │ login` or a CI OIDC token. A failed upload is │ │ reported and never changes the exit code │ │ --cloud-policy apply the organisation policy and approved │ │ suppressions from Cordon Cloud, verified against │ │ the policy key pinned at sign-in. Replaces │ │ --policy. If no current, verified bundle is │ │ available the scan does not run (exit 3) │ │ --cloud-url URL Cordon Cloud API base (default: │ │ CORDON_CLOUD_URL, else https://api.cordon.dev) │ │ --no-expand do not open archives found inside a directory │ │ scan. Faster, and the scan is then marked │ │ incomplete if any archive went unopened │ │ --quiet, -q findings only │ │ --verbose, -v more detail │ │ --no-color disable colour │ │ --audit-log PATH append one JSON line per scan recording what ran │ │ and what was suppressed; never file content │ │ --progress {auto,always,never} │ │ show a live progress line on stderr; auto means │ │ only when stderr is an interactive terminal │ └────────────────────────────────────────────────────────────────────────────┘
Clone a repository, scanning it before any file is checked out.
Clone without checking out, scan the commit from git's object store, then check it out. A blocked clone is removed, so nothing of it is left on disk.
┌────────────────────────────────────────────────────────────────────────────┐ │ url the repository to clone │ │ directory where to clone it (default: its name) │ │ --branch, -b NAME check out this branch │ │ --fail-on SEVERITY also block on findings at or above this severity │ │ (default: critical; anything malicious always │ │ blocks) │ │ --config PATH your own configuration; the repository's is │ │ never read │ └────────────────────────────────────────────────────────────────────────────┘
Fetch, scan what would be merged, and merge only if it passes.
Fetch the branch, scan the incoming commit from git's object store, and merge only when it passes. Findings your checkout already had are not counted again. A blocked pull leaves the checkout exactly as it was.
┌────────────────────────────────────────────────────────────────────────────┐ │ remote the remote (default: the branch's upstream) │ │ branch the branch on that remote │ │ --merge allow a merge commit; fast-forward only by │ │ default │ │ --fail-on SEVERITY also block on findings at or above this severity │ │ (default: critical; anything malicious always │ │ blocks) │ │ --config PATH your own configuration; the incoming code's is │ │ never read │ │ -C PATH the repository (default: .) │ └────────────────────────────────────────────────────────────────────────────┘
Print what the repository is, and the evidence for it.
┌────────────────────────────────────────────────────────────────────────────┐
│ target │
│ --format, -f {text,json} │
└────────────────────────────────────────────────────────────────────────────┘Dependency graph and per-package findings.
┌────────────────────────────────────────────────────────────────────────────┐
│ target path to scan (default: .) │
│ --format {text,json} │
│ --direct-only list direct dependencies only │
│ --online also ask registries (withdrawal, hashes, │
│ provenance) │
└────────────────────────────────────────────────────────────────────────────┘What a dependency update adds, compared with a git revision.
┌────────────────────────────────────────────────────────────────────────────┐
│ target repository directory (default: .) │
│ --base REF the revision to compare with, e.g. origin/main │
│ --format {text,markdown,json} │
│ --online fetch each changed package's old and new │
│ releases from its registry, verify, scan and │
│ compare them │
│ --quiet no progress on stderr │
└────────────────────────────────────────────────────────────────────────────┘Generate or inspect a bill of materials for a scan target.
┌────────────────────────────────────────────────────────────────────────────┐ │ sbom generate write a CycloneDX or SPDX document from the │ │ resolved graph │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ target │
│ --format {cyclonedx,spdx} │
│ --output, -o PATH │
│ --ai write the AI bill of materials instead │
│ (CycloneDX 1.6): agent instruction, skill and │
│ prompt files, agent settings, MCP servers, │
│ models and AI SDKs │
│ --vulnerabilities embed the advisory matches (CycloneDX │
│ `vulnerabilities`), marking those on CISA KEV or │
│ ENISA EUVD as exploited: the per-release record │
│ the EU Cyber Resilience Act asks a manufacturer │
│ to keep │
│ --name NAME root component name (default: directory name) │
│ --component-version VERSION │
│ root component version (default: whatever the │
│ target's own manifest declares, or 0.0.0 when it │
│ declares none) │
└────────────────────────────────────────────────────────────────────────────┘Re-render a saved JSON result in another format.
┌────────────────────────────────────────────────────────────────────────────┐ │ report convert render a saved result │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path a result written with --format json │ │ --format, -f FORMAT text|json|sarif|junit|markdown|github │ │ --output, -o OUTPUT write to a file │ └────────────────────────────────────────────────────────────────────────────┘
rules: list, test and show the rulesconfig: check the repository configurationbaseline: record findings, adopt graduallysuppress: reviewed, expiring exceptionsguard: git hooks and self-integrity
Inspect and validate rule packs.
┌────────────────────────────────────────────────────────────────────────────┐ │ rules list list every loaded rule │ │ rules test run every rule's declared samples │ │ rules diff compare rule packs and report removal or │ │ weakening │ │ rules show show one rule in full │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ before a pack file, or a directory of packs │ │ after the pack to compare; defaults to the packs built │ │ into this install │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ rule_id │ └────────────────────────────────────────────────────────────────────────────┘
Check configuration.
┌────────────────────────────────────────────────────────────────────────────┐ │ config validate validate a configuration file │ │ config fetch-policy fetch a digest-pinned organisation policy │ │ once, so scans read it offline │ │ config policy-drift check a vendored policy copy against the │ │ published one (exit 1 when they differ) │ │ config explain show effective settings and their origin │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path │ │ --policy PATH │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ url https://host/policy.yaml#sha256=<64 hex> │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ vendored the copy in this repository │ │ --published PUBLISHED the published policy: a path, or its URL with │ │ #sha256=<hex> (compared by digest, nothing │ │ fetched) │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path │ │ --policy PATH │ └────────────────────────────────────────────────────────────────────────────┘
Record known findings so a tool can be adopted incrementally.
┌────────────────────────────────────────────────────────────────────────────┐ │ baseline create record the current findings │ │ baseline compare report findings outside the baseline │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ target │ │ --output, -o OUTPUT where to write it │ │ --policy PATH │ │ --all-files include files git ignores; by default a baseline │ │ inside a repository covers tracked files only │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ target │ │ BASELINE │ │ --policy PATH │ │ --all-files include files git ignores; by default a baseline │ │ inside a repository covers tracked files only │ └────────────────────────────────────────────────────────────────────────────┘
List, add and prune suppressions in the repository config.
┌────────────────────────────────────────────────────────────────────────────┐ │ suppress list show every suppression and whether it is in │ │ force │ │ suppress add add a suppression, checked as the scanner │ │ checks it │ │ suppress prune remove expired suppressions and report them │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ --root ROOT repository root (default: .) │
│ --config CONFIG config file to edit (default: the repository's │
│ cordon.yaml) │
│ --policy POLICY organisation policy whose ceiling suppressions │
│ must respect │
│ --format {text,json} │
└────────────────────────────────────────────────────────────────────────────┘┌────────────────────────────────────────────────────────────────────────────┐ │ --root ROOT repository root (default: .) │ │ --config CONFIG config file to edit (default: the repository's │ │ cordon.yaml) │ │ --policy POLICY organisation policy whose ceiling suppressions │ │ must respect │ │ rule the rule id, e.g. SUSPECT.SPAWN.001 │ │ path the path it applies to (no `**`) │ │ --justification JUSTIFICATION │ │ why this is safe here (at least 40 characters) │ │ --expires EXPIRES expiry date, YYYY-MM-DD │ │ --days DAYS expire this many days from today (default 30) │ │ --approved-by APPROVED_BY who approved it (required when policy demands an │ │ approver) │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ --root ROOT repository root (default: .) │ │ --config CONFIG config file to edit (default: the repository's │ │ cordon.yaml) │ │ --policy POLICY organisation policy whose ceiling suppressions │ │ must respect │ │ --dry-run report what would be removed, change nothing │ └────────────────────────────────────────────────────────────────────────────┘
Scanner self-integrity and git hook installation.
┌────────────────────────────────────────────────────────────────────────────┐ │ guard verify check that the guard is intact │ │ guard install install fail-closed git hooks │ │ guard update regenerate the guard hash manifest │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path │ │ --manifest-only check only that every file the guard manifest │ │ lists matches it; for CI, which has no hooks to │ │ check │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path │ │ --global install into git's template directory, so every │ │ repository cloned or created from now on has the │ │ hooks │ │ --force replace a pre-existing non-cordon hook. Without │ │ this such a hook is preserved and a backup is │ │ written beside it │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ path │ └────────────────────────────────────────────────────────────────────────────┘
advisories: the advisory databaseintel: the signed threat-intel feedbundle: offline bundle for air-gapped use
Manage the vulnerability/malicious-package advisory database.
┌────────────────────────────────────────────────────────────────────────────┐ │ advisories sync refresh the local advisory data from OSV's │ │ bulk export │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ --only ECOSYSTEM sync only these ecosystems (default: all │ │ supported) │ │ --os FAMILY also sync these distributions' advisories │ │ (debian, ubuntu, alpine, wolfi, chainguard, │ │ rocky, almalinux, redhat, suse, opensuse) so │ │ image scans match operating-system packages │ │ offline │ │ --bundle URL install a signed advisory bundle from URL │ │ instead of building from OSV; the bundle's │ │ Ed25519 signature is verified against the pinned │ │ release key before anything is unpacked │ └────────────────────────────────────────────────────────────────────────────┘
The signed threat-intel feed: how current it is, and refreshing it.
┌────────────────────────────────────────────────────────────────────────────┐ │ intel status show the intel's source, serial and age │ │ without fetching anything │ │ intel update verify and apply the latest signed feed now │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ --json print as JSON │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ --json print as JSON │ └────────────────────────────────────────────────────────────────────────────┘
Build and verify an offline bundle for an air-gapped install.
┌────────────────────────────────────────────────────────────────────────────┐ │ bundle create build a bundle from a directory │ │ bundle verify check a bundle against its manifest │ │ bundle install verify a bundle, then extract it │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ source directory holding the files to bundle │ │ --output, -o PATH │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ BUNDLE │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ BUNDLE │ │ --into DIR │ └────────────────────────────────────────────────────────────────────────────┘
login: sign in to Cordon Cloud (SSO)logout: end the Cordon Cloud sign-inwhoami: the Cordon Cloud sign-in in userunner: run Cloud jobs in your networkagent: AI agents and MCP servers, for MDM
Sign in to Cordon Cloud through your organisation's SSO (device flow).
┌────────────────────────────────────────────────────────────────────────────┐ │ --url URL Cordon Cloud API base │ └────────────────────────────────────────────────────────────────────────────┘
Forget the stored Cordon Cloud sign-in.
Show the Cordon Cloud sign-in in use.
Run scan jobs from Cordon Cloud inside your own network (outbound only).
┌────────────────────────────────────────────────────────────────────────────┐ │ --url URL Cordon Cloud API base │ │ --allow-host HOST a host the runner may clone or download from │ │ (repeat); jobs naming any other are refused │ │ --label LABEL a label jobs can target (repeat) │ │ --git-credential HOST=ENV clone private repositories on HOST with the │ │ credential in environment variable ENV: a token, │ │ or user:token (repeat). For GitLab and │ │ Bitbucket, which cannot mint a token per clone │ │ --id ID this runner's name (default: the host name) │ │ --work-dir WORK_DIR where job workspaces are created and removed │ │ --once take at most one job, then exit │ │ --allow-online let jobs ask for registry lookups (off: the │ │ cloud cannot turn on network use here) │ │ --make-fixes also take fix jobs: move one npm or PyPI │ │ dependency to a safe version in its lockfile and │ │ push a branch (no package manager or package │ │ code is run). Off by default │ └────────────────────────────────────────────────────────────────────────────┘
This machine's AI agents and MCP servers, for an organisation's MDM (read-only, disclosed).
┌────────────────────────────────────────────────────────────────────────────┐ │ agent inventory print exactly what `agent report` would │ │ send; sends nothing │ │ agent report send the inventory with the MDM's device │ │ token │ │ agent mcp-approve record the tools each remote MCP server in │ │ the repository serves now (.cordon/mcp- │ │ tools.json) │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ --url URL Cordon Cloud API base │ └────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐ │ target repository directory (default: .) │ └────────────────────────────────────────────────────────────────────────────┘
help: this screen, or one command's helpcompletion: shell completion script
This screen, or the help for one command.
┌────────────────────────────────────────────────────────────────────────────┐ │ COMMAND a command, or a command and its action │ └────────────────────────────────────────────────────────────────────────────┘
Print a shell completion script.
┌────────────────────────────────────────────────────────────────────────────┐ │ shell │ └────────────────────────────────────────────────────────────────────────────┘