Advanced CLI

Power-user commands: diff evaluations, rank findings, JSON output, and automation scripts.

sofe diff — Compare Evaluations

Compare two evaluations to see what changed (new findings, fixed findings, unchanged).

sofe diff <eval-id-1> <eval-id-2>
Example output
Evaluation Diff
  A: fb57f2f6 (48 findings) — 2026-07-09T06:00
  B: a3c8d921 (45 findings) — 2026-07-08T06:00

  +2 new  -5 fixed  =43 unchanged

  + New findings (appeared in B):
    H new-s3-bucket     no-public-access
    M new-lambda        require-cost-tags

  - Fixed findings (resolved in B):
    M old-ec2           no-idle-ec2
    M old-lambda        require-cost-tags
    ...

Matching: same policy_name + resource_id = same finding.

Finding eval IDs

# Get IDs from history
sofe history

# Or from evaluate output
sofe evaluate --cloud
# → ID: fb57f2f6-e387-4327-8a63-d05c11f505d4

sofe top — Rank Findings

See which policies trigger the most findings, ranked by frequency.

sofe top
Top Findings by Frequency
  Based on latest evaluation (57 findings)

┌───┬───────────────────────────┬───────┬──────────┬─────────────────────┐
│ # │ POLICY                    │ COUNT │ SEVERITY │ RESOURCES (SAMPLE)  │
├───┼───────────────────────────┼───────┼──────────┼─────────────────────┤
│ 1 │ require-cost-tags         │    46 │ medium   │ htmlprueba, +43     │
│ 2 │ api-gateway-no-throttling │     8 │ medium   │ ViajesSalvajes, +5  │
│ 3 │ secrets-not-rotated       │     2 │ medium   │ awsorg/events/root  │
│ 4 │ no-public-without-waf     │     1 │ high     │ EHMQGKJRB7VUA       │
└───┴───────────────────────────┴───────┴──────────┴─────────────────────┘

Use this to prioritize: fix the top policy first for maximum impact.

JSON Output for Automation

All commands support --format json for piping to other tools.

# Get findings as JSON
sofe evaluate --cloud --format json > findings.json

# Filter high-severity with jq
sofe evaluate --cloud --format json | jq '.findings[] | select(.severity=="high")'

# Count findings per policy
sofe evaluate --cloud --format json | jq '[.findings[].policy_name] | group_by(.) | map({policy: .[0], count: length})'

# Get eval ID programmatically
EVAL_ID=$(sofe evaluate --cloud --format json | jq -r '.evaluation_id')
sofe explain $EVAL_ID -f 0

Scripting Examples

Daily regression check

#!/bin/bash
# Run eval, check for regressions
RESULT=$(sofe evaluate --cloud --format json)
FINDINGS=$(echo $RESULT | jq '.findings_count')
HIGH=$(echo $RESULT | jq '[.findings[] | select(.severity=="high")] | length')

if [ "$HIGH" -gt 0 ]; then
  echo "⚠️ $HIGH high-severity findings detected"
  echo $RESULT | jq '.findings[] | select(.severity=="high") | .resource_id'
  exit 1
fi
echo "✅ No high-severity findings ($FINDINGS total)"

Slack notification on new findings

#!/bin/bash
# Compare last 2 evals and notify if degrading
STATUS=$(sofe watch --once 2>&1)
if echo "$STATUS" | grep -q "degrading"; then
  curl -X POST "$SLACK_WEBHOOK" \
    -d "{\"text\":\"⚠️ SOFE findings increasing\n$STATUS\"}"
fi

Environment Variables

VariableUse
SOFE_API_KEYAPI key (overrides config)
SOFE_CLOUD_URLCustom API URL
NO_COLORDisable colors (standard)