Code Security Scanning
Caged automatically scans agent code changes for security issues before they reach your repository. Every git commit and git push can trigger:
- SAST scanning — Static analysis for SQL injection, XSS, insecure crypto
- Secret detection — Find leaked API keys, passwords, tokens, private keys
- Dependency scanning — Identify vulnerable packages in manifests
How It Works
When an agent runs git commit or git push inside a sandbox:
- Caged intercepts the git command via MCP tool hooks
- Scans the changed files using configured scanners
- Compares findings against your policy's severity threshold
- Blocks the operation if critical/high issues are found
- Records the scan report for observability
flowchart LR
A[Agent: git commit] --> B[Scan Hook]
B --> C[SAST + Secrets + Deps]
C --> D{Threshold<br/>exceeded?}
D -->|No| E[✓ Commit allowed]
D -->|Yes| F[✗ Commit blocked]
Enabling Scans
Output scanning is controlled by policies. Add an output_scan scope to your sandbox policy:
# In your policy.yaml or via API
rules:
- scope: output_scan
action: deny
config:
severity_threshold: high # Block if findings >= high
scan_types:
- sast
- secret
- dependency
message: "Security scan failed. Fix issues before committing."
Severity Levels
| Level | Examples |
|---|---|
critical |
RCE, SQL injection, leaked private keys |
high |
XSS, hardcoded secrets, critical CVEs |
medium |
Insecure defaults, medium CVEs |
low |
Deprecated functions, low CVEs |
info |
Style issues, informational findings |
Scan Types
| Type | Scanner | What It Finds |
|---|---|---|
sast |
Semgrep | Code patterns: injection, XSS, crypto issues |
secret |
Gitleaks | API keys, passwords, tokens, private keys |
dependency |
Trivy | Vulnerable packages in package.json, go.mod, requirements.txt |
CLI Commands
Run a scan manually
caged scan run sbx_abc123
# Scan specific types
caged scan run sbx_abc123 --types=sast,secret
# Scan only changed files (diff against HEAD~1)
caged scan run sbx_abc123 --diff=HEAD~1
# JSON output
caged scan run sbx_abc123 --json
List scan reports
caged scan list --sandbox=sbx_abc123
caged scan list --session=sess_xyz
Get scan details
caged scan get <report-id>
caged scan get <report-id> --json
API Reference
Trigger a Scan
POST /v1/scans
{
"sandbox_id": "sbx_abc123",
"session_id": "sess_xyz", // optional
"work_dir": "/workspace",
"diff_ref": "HEAD~1", // optional, scan only changed files
"scan_types": ["sast", "secret"] // optional, defaults to all
}
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"sandbox_id": "sbx_abc123",
"session_id": "sess_xyz",
"blocked": false,
"total_count": 3,
"by_severity": {
"medium": 2,
"low": 1
},
"by_type": {
"sast": 2,
"secret": 1
},
"results": [
{
"scanner_name": "semgrep",
"scan_type": "sast",
"findings": [
{
"title": "Possible SQL injection",
"severity": "medium",
"file_path": "api/users.go",
"start_line": 45,
"end_line": 45,
"code_snippet": "query := fmt.Sprintf(\"SELECT * FROM users WHERE id = %s\", id)",
"suggestion": "Use parameterized queries instead of string interpolation"
}
]
}
]
}
List Scan Reports
GET /v1/scans?sandbox_id=sbx_abc123&limit=20
GET /v1/scans?session_id=sess_xyz&limit=20
Get Scan Report
GET /v1/scans/:id
Skipping Scans
Agents can skip scans for specific commits using the skip_scan argument:
{
"name": "git_commit",
"arguments": {
"message": "WIP: checkpoint",
"skip_scan": true
}
}
Skipping scans should be rare. All skipped commits are logged and visible in session replay.
Events
Each scan emits an event to NATS JetStream for observability:
{
"type": "output_scan",
"sandbox_id": "sbx_abc123",
"session_id": "sess_xyz",
"scan_id": "uuid",
"total_findings": 5,
"by_severity": {"high": 2, "medium": 3},
"blocked": true,
"block_reason": "2 high-severity findings exceed threshold"
}
Dashboard
Scan findings are visible in:
- Session timeline — Scan events appear inline with file changes
- File diff view — Findings annotated on affected lines
- Sandbox overview — Summary of recent scans with block status
Best Practices
Set action: warn initially to see what gets flagged without blocking agents
Lower threshold to medium for production codebases, keep high for prototypes
Add Semgrep rules for your specific patterns (internal API usage, deprecated methods)
Monitor scan events over time to catch agents that consistently produce risky code