CLI Reference
Complete reference for all scd commands.
Commands and output below describe the latest scd release. On an older version, run scd version and check the release notes for differences. Items marked (since x.y) were added in that release.
Scanning
| Command | Description |
|---|---|
scd scan | Full security scan — vendor and .gitignored files excluded by default |
scd scan --verbose | Full file-grouped + rule-grouped output |
scd scan --deep | Deep AI-powered analysis via scd-server (Premium). If AI is disabled on the server or the server is unreachable, the scan continues with a warning — it does not fail |
scd scan --include-vendor | Include vendor/dependency code |
scd scan --vendor-only | Scan only vendor/dependency code (supply chain) |
scd scan --include-ignored | Scan files excluded by .gitignore |
scd scan --exclude <pattern> | Exclude a file or directory for this scan only (repeatable, not saved) |
scd scan --exclude-rule <id> | Exclude a rule for this scan only (repeatable, not saved) |
scd scan --log-to <mode> | Logging mode for non-interactive use: none, current, target |
scd scan --max-findings <n> | Show and analyse top N findings (sorted by severity) — does not affect scan coverage, audit log, or cache |
scd scan --no-sync | Skip pushing this scan to scd-server (Premium) |
scd scan --no-audit | Skip audit logging for this scan |
--exclude and --exclude-rule — one-off scan exclusions
Exclude files or rules for a single scan without modifying scope.yml. Useful for quick ad-hoc filtering or testing.
scd scan --exclude "tests/fixtures/" --exclude-rule INFRA-002
One-off exclusions are shown in scan output and stored in the scan JSON, but never written to disk. For permanent exclusions, use scd repo scope.
--log-to — non-interactive and pipeline use
When scd scan runs without a TTY (CI/CD pipeline, subprocess), it auto-detects the missing terminal and scans without logging — no prompt, no hanging.
Use --log-to for explicit control in automated contexts:
| Value | Behaviour |
|---|---|
none | Scan without logging, no prompt |
current | Log results to the current working directory's repo, no prompt |
target | Log results to the target repository's repo, no prompt |
Reports
| Command | Description |
|---|---|
scd report | Generate HTML report from last scan |
scd report open | Generate and open in browser (macOS / Windows) |
scd report serve | Serve report via local HTTP server (Linux / Firefox) |
scd report serve --index | Always show report index page |
scd report --scan <id> | Generate report from a specific saved scan |
scd export-findings | Export all findings from a scan to JSON |
scd export-findings --deep-only | Export only findings with a deep analysis result |
scd export-findings --severity critical | Filter by severity |
scd export-findings --scan <id> | Export from a specific saved scan |
Findings
| Command | Description |
|---|---|
scd findings | List open findings from last scan |
scd findings <finding-id> | Show a specific finding with full detail |
scd findings --verbose | All open findings with problem, scenario, and fix |
scd findings --by-file | Group findings by file instead of by severity (since 1.5.0) |
scd findings --show-suppressed | Show findings suppressed by file context classification |
scd findings --all | All findings including excepted and resolved |
scd findings --excepted | Only excepted findings |
scd findings --severity critical | Filter by severity |
scd findings --rule <id> | Filter by rule ID |
scd findings --scan <id> | Load a specific historic scan |
Suppressed findings
Before any rule runs, scd builds a file manifest that classifies every file into one of three scan contexts:
- source — production code, scanned with the full rule set
- test — test and fixture files, routed to a separate rule set
- excluded — vendor and generated files, not scanned
The manifest summary is shown at the start of every scan:
38 source · 4 test (separate context) · 1 excluded (vendor/generated)
Findings in test and fixture files may be suppressed or have their severity reduced. When suppressions exist, scan output shows a summary line after the findings list:
10 finding(s) suppressed by file context · scd findings --show-suppressed
scd findings --show-suppressed shows each suppressed finding with its base severity, effective score, file context classification, and the modifiers that caused the suppression. Normal findings output shows a downgrade indicator (↓ HIGH → MEDIUM) when context reduced but did not suppress a finding.
Exception management
Exceptions are managed by finding ID — shown in scan output, reports, and scd findings. Never edit source code comments.
| Command | Description |
|---|---|
scd accept <finding-id> --reason <text> | Accept finding as acceptable risk |
scd accept <finding-id> --tag <text> | Optional tag, e.g. false_positive, out_of_scope |
scd accept <finding-id> --review-in <30d|2w|3m> | Set a review deadline — the exception auto-expires and the finding reopens (since 1.5.0) |
scd ignore <finding-id> --reason <text> | Ignore a finding (also accepts --tag and --review-in) |
scd sync | Pull approved/rejected exceptions from scd-server (Premium) |
scd exceptions | List all local exceptions |
scd exceptions --list rejected | List only rejected exceptions |
scd exceptions --list pending|approved|rejected|archived|all | Filter by status |
scd exceptions withdraw <id> | Withdraw an exception — archives it locally (never deletes) (since 1.5.0) |
Exception workflow
# View open findings with their IDs
scd findings
# Accept a risk
scd accept f-a1b2c3d4 --reason "Parameterized internally, validated input only"
# Pull approvals/rejections from team server
scd sync
# List exceptions and their status
scd exceptions --list all
# Withdraw an exception you no longer need (archived locally, never deleted)
scd exceptions withdraw exc-mn7k96ml
After scd sync, the next scan shows pending status inline:
ℹ 2 exception(s) pending approval – run scd sync to refresh
⚠ 1 rejected exception(s) — fix required:
PHP-INJ-002 WS_addUser.php:10 [exc-mn7k96ml]
Exceptions include a hash of the relevant code line. If the code changes, the exception requires re-approval automatically.
History and navigation
| Command | Description |
|---|---|
scd audit | View scan history and audit trail |
scd insights | Analyze behavioral patterns from audit log |
scd rules | List all 189 security rules |
scd rules --lang php | Filter rules by language |
scd rules --id INFRA-001 | Show full detail for a rule |
scd rules --search "injection" | Free-text search across rules |
scd rules --stats | Rule counts by severity and language |
scd list | List all repos registered in store |
scd list verify | Verify all repos exist on disk |
scd list verify --clean | Interactive cleanup of missing/stale repos |
scd repo | Show store info for current repo |
scd repo show | Full metadata for current repo |
scd repo scans | List all saved scans |
scd repo reports | List saved reports for this repo |
scd repo findings | List findings for this repo (alias for scd findings) |
scd repo exceptions | List exceptions for this repo (alias for scd exceptions) |
scd remove | Remove current repo from store |
Scope management
Scope exclusions let you permanently exclude files, directories, or rules from all scans, with a mandatory documented reason. Every active exclusion is shown prominently in scan output and logged to the audit trail.
For one-off per-scan exclusions without modifying scope, use scd scan --exclude and scd scan --exclude-rule.
Global scope (applies to all repos)
| Command | Description |
|---|---|
scd scope --show | Show global scope exclusions |
scd scope --add-file <pattern> --reason <text> | Exclude files/directories globally |
scd scope --add-rule <id> --reason <text> | Exclude a rule globally |
scd scope --remove-file <pattern> --reason <text> | Remove a global file exclusion |
scd scope --remove-rule <id> --reason <text> | Remove a global rule exclusion |
Per-repo scope
| Command | Description |
|---|---|
scd repo scope --show | Show merged scope for current repo (global + repo + server) |
scd repo scope --add-file <pattern> --reason <text> | Exclude files/directories for this repo |
scd repo scope --add-rule <id> --reason <text> | Exclude a rule for this repo |
scd repo scope --remove-file <pattern> --reason <text> | Remove a repo file exclusion |
scd repo scope --remove-rule <id> --reason <text> | Remove a repo rule exclusion |
Example
# Exclude a test fixtures directory for this repo
scd repo scope --add-file "tests/fixtures/" --reason "Intentional vulnerability examples"
# Exclude an infrastructure rule globally (cloud-managed infra)
scd scope --add-rule INFRA-001 --reason "Cloud-managed infrastructure"
# Exclude a rule for specific files only
scd repo scope --add-rule JS-ERR-002 --files "lib/rules/,**/*.test.js" --reason "Rule definition files"
# Show what's currently excluded
scd repo scope --show
Hook management
| Command | Description |
|---|---|
scd hooks | Show hook status across all registered repos |
scd repo hooks | Show hook status for the current repo |
scd repo hooks disable --reason <text> | Disable hooks for current repo (requires reason) |
scd repo hooks enable | Re-enable hooks for current repo |
Hook disables are logged to audit.log and pushed to scd-server so team leads can see them.
The older
scd repo hooks --disable/--enableflag forms still work but are deprecated — prefer thedisable/enablesubcommands above.
Setup and configuration
| Command | Description |
|---|---|
scd install | Install git hooks globally (once per machine) |
scd uninstall | Remove git hooks and global git config |
scd init | Register current project (once per project) |
scd doctor | Verify setup, connection, push queue status, and AI provider status |
scd version | Show version and rule counts |
scd configure --central-url <url> | Set scd-server URL |
scd configure --token <token> | Set API token |
scd configure --server-timeout <duration> | Regular API call timeout (default: 30s) |
scd configure --deep-timeout <duration> | Deep analysis timeout (default: 20m) |
scd configure --scan-mode <fast|full> | Set global default scan mode |
scd configure --trust-level <value> | Set global default trust level |
scd configure --block-on-high <bool> | Set global default block-on-high |
scd configure --block-on-critical <bool> | Set global default block-on-critical |
scd configure --unset <key> | Clear a global setting (e.g. --unset trust-level) so it falls back to the built-in default (since 1.5.1) |
scd queue | Inspect the offline push queue; scd queue reset retries delivery of any stuck events (since 1.5.0) |
Per-repo configuration
| Command | Description |
|---|---|
scd repo configure | Show config with source (repo/global/default) |
scd repo configure --scan-mode fast|full | Set scan mode |
scd repo configure --trust-level <value> | Set trust level |
scd repo configure --block-on-high <bool> | Set blocking behaviour for HIGH findings |
scd repo configure --block-on-critical <bool> | Set blocking behaviour for CRITICAL findings |
scd repo configure --unset <key> | Clear a repo setting (e.g. --unset trust-level) so it falls back to global, then the default (since 1.5.1) |
scd repo configure creates the per-repo config on demand — you no longer need to run scd init first to change a setting (since 1.5.1).
Trust levels
| Value | Behaviour |
|---|---|
maximum_privacy | No external API calls. Local model only. Strongest privacy guarantee. |
balanced | Default. Local model preferred; cloud available as explicit opt-in. |
maximum_analysis | Cloud provider (Claude API). Maximum analysis depth. |
Set with:
scd repo configure --trust-level maximum_privacy
Scan IDs and finding IDs
Every scan gets a unique ID (s-a3f9b2c1) shown in terminal output. Every finding gets a stable ID (f-a1b2c3d4). Use these IDs directly with scd accept, scd ignore, scd findings, and scd report --scan.
IDs are random, not time-based — no timezone issues when working across machines.