go-agent/claude/agentic/scripts/security-scan.sh
Snider 61e01bfdf1 feat: initial go-agent — agentci + jobrunner + plugins marketplace
Consolidates three codebases into a single agent orchestration repo:

- agentci (from go-scm): Clotho dual-run verification, agent config,
  SSH security (sanitisation, secure commands, token masking)
- jobrunner (from go-scm): Poll-dispatch-report pipeline with 7 handlers
  (dispatch, completion, auto-merge, publish draft, dismiss reviews,
  send fix command, tick parent epic)
- plugins marketplace (from agentic/plugins): 27 Claude/Codex/Gemini
  plugins with shared MCP server

All 150+ tests passing across 6 packages.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-21 15:47:19 +00:00

92 lines
3.4 KiB
Bash
Executable file

#!/bin/bash
# Sovereign security scanning — local developer workflow
# Usage: security-scan.sh [path] [--fix]
# Runs: govulncheck, gitleaks, trivy
# No cloud dependencies. PCI DSS Req 6.3.2 / 11.3 compliant.
set -euo pipefail
TARGET="${1:-.}"
FIX_MODE="${2:-}"
PASS=0
FAIL=0
WARN=0
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
DIM='\033[0;90m'
RESET='\033[0m'
header() { echo -e "\n${GREEN}=== $1 ===${RESET}"; }
pass() { echo -e " ${GREEN}PASS${RESET} $1"; ((PASS++)); }
fail() { echo -e " ${RED}FAIL${RESET} $1"; ((FAIL++)); }
warn() { echo -e " ${YELLOW}WARN${RESET} $1"; ((WARN++)); }
dim() { echo -e " ${DIM}$1${RESET}"; }
echo "Security Scan: $(realpath "$TARGET")"
echo "Date: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
# --- Go vulnerability check ---
if [ -f "$TARGET/go.mod" ]; then
header "Go Vulnerability Check (govulncheck)"
GOVULNCHECK=$(command -v govulncheck 2>/dev/null || echo "$HOME/go/bin/govulncheck")
if [ -x "$GOVULNCHECK" ]; then
GOVULN_OUT=$( (cd "$TARGET" && $GOVULNCHECK ./... 2>&1) || true)
if echo "$GOVULN_OUT" | grep -q "No vulnerabilities found"; then
pass "No Go vulnerabilities found"
else
VULN_COUNT=$(echo "$GOVULN_OUT" | grep -c "^Vulnerability #" || true)
if [ "$VULN_COUNT" -gt 0 ]; then
warn "$VULN_COUNT Go vulnerabilities found (run govulncheck ./... for details)"
else
pass "govulncheck completed"
fi
fi
else
dim "govulncheck not installed (go install golang.org/x/vuln/cmd/govulncheck@latest)"
fi
fi
# --- Secret detection ---
header "Secret Detection (gitleaks)"
GITLEAKS=$(command -v gitleaks 2>/dev/null || echo "$HOME/.local/bin/gitleaks")
if [ -x "$GITLEAKS" ]; then
if $GITLEAKS detect --source "$TARGET" --no-banner --no-git 2>&1 | grep -q "no leaks found"; then
pass "No secrets detected in working tree"
else
LEAK_COUNT=$($GITLEAKS detect --source "$TARGET" --no-banner --no-git --report-format json --report-path /dev/stdout 2>/dev/null | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo "?")
fail "$LEAK_COUNT potential secrets found (run gitleaks detect --source $TARGET -v)"
fi
else
dim "gitleaks not installed"
fi
# --- Dependency & filesystem scan ---
header "Dependency Scan (trivy)"
TRIVY=$(command -v trivy 2>/dev/null || echo "$HOME/.local/bin/trivy")
if [ -x "$TRIVY" ]; then
TRIVY_OUT=$($TRIVY fs --scanners vuln --severity HIGH,CRITICAL --quiet "$TARGET" 2>&1 || true)
if echo "$TRIVY_OUT" | grep -q "Total: 0"; then
pass "No HIGH/CRITICAL vulnerabilities in dependencies"
elif [ -z "$TRIVY_OUT" ]; then
pass "No vulnerable dependencies found"
else
TRIVY_VULNS=$(echo "$TRIVY_OUT" | grep -oP 'Total: \K\d+' | awk '{s+=$1}END{print s}' 2>/dev/null || echo "?")
warn "$TRIVY_VULNS HIGH/CRITICAL dependency vulnerabilities"
echo "$TRIVY_OUT" | grep -E '│|Total:' | head -20
fi
else
dim "trivy not installed"
fi
# --- Summary ---
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e " ${GREEN}PASS: $PASS${RESET} ${YELLOW}WARN: $WARN${RESET} ${RED}FAIL: $FAIL${RESET}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ "$FAIL" -gt 0 ]; then
exit 1
fi
exit 0