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:

  1. Caged intercepts the git command via MCP tool hooks
  2. Scans the changed files using configured scanners
  3. Compares findings against your policy's severity threshold
  4. Blocks the operation if critical/high issues are found
  5. 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:

  1. Session timeline — Scan events appear inline with file changes
  2. File diff view — Findings annotated on affected lines
  3. 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

Was this page helpful?