b4d9409e4d
Wave A of P03. Wires the three security tools into the
.coreci.yml pipeline and exposes them via a
local make target.
- .gitleaks.toml (REQ-039) — allowlist for cert PEM blocks
(-----BEGIN CERTIFICATE-----), test data paths, and
self-references. Stopwords suppress the false-positive
on cert headers without disabling the real secret
detection for private keys.
- .gitleaks-baseline.json (REQ-029) — suppresses the v0.1
historical .env leak (rotated forward in 00127ce) so
CI doesn't fail on the existing history. The baseline
format matches gitleaks 8.x.
- .golangci.yml (REQ-040) — unified lint config with
gosec, govet, ineffassign, misspell, gocritic. gosec
severity=high so G101 (hardcoded credentials) is a
build-breaker. Excludes _test.go for G404 (math/rand
is fine in tests) and internal/security/testdata/.
- .githooks/pre-commit — gitleaks protect --staged;
commits are still allowed when gitleaks is not on PATH
(gate, not block; CI catches findings via .coreci.yml).
- scripts/security_scan.sh — wrapper that runs all three
tools, exits non-zero on any unsuppressed finding.
Detects missing tools and SKIPs in dev mode (--strict
flips to FAIL on skip). Used by ./scripts/security_scan.sh
─── gosec ─────────────────────────────────────
⚠ gosec: SKIP (not installed)
─── govulncheck ─────────────────────────────────────
⚠ govulncheck: SKIP (not installed)
─── gitleaks ─────────────────────────────────────
⚠ gitleaks: SKIP (not installed)
─── summary ─────────────────────────────────────
0 pass, 0 fail, 3 skip
✓ security-scan PASSED.
- docs/security-scanning.md — operator-facing doc covering
each tool, the offline mode (REQ-027) for govulncheck
via GOFLAGS=-mod=mod, the pre-mirrored DB mechanism
(GOVULNCHECK_DB), and how to add baseline entries.
- .coreci.yml — validate pipeline gains three new stages
in order gosec, govulncheck, gitleaks. Test pipeline
runs with -race (REQ-031). Release pipeline's tea
invocation now passes --repo coreci/orca (P01 audit
fix; was previously missing).
- Makefile — adds test-race and security-scan targets;
help text updated.
- scripts/release.sh — tea releases create now passes
--repo coreci/orca (P01 audit fix; the missing flag
required manual workaround in P01 + P02 ship).
All builds clean; tests pass with -race; gofmt -l . clean;
go vet ./... clean.
---ci---
project: orca
phase: 10
milestone: v0.2
status: execute
---/ci---
104 lines
2.9 KiB
Bash
Executable File
104 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# security_scan.sh — run gosec, govulncheck, and gitleaks on the
|
|
# orca repo. Local equivalent of the .coreci.yml `validate` security
|
|
# stages. Exits non-zero on any unsuppressed finding.
|
|
#
|
|
# Tool detection: a tool that's not installed is SKIPPED (warning
|
|
# printed). The .coreci.yml `validate` pipeline requires all three;
|
|
# the local `make security-scan` is opt-in for developer machines.
|
|
#
|
|
# Usage: scripts/security_scan.sh [--strict]
|
|
# --strict All three tools must be present and pass.
|
|
#
|
|
# REQ-014: gosec + govulncheck in CI
|
|
# REQ-027: govulncheck runs in offline mode
|
|
# REQ-039: gitleaks allowlist for cert PEM blocks
|
|
# REQ-040: golangci-lint as the unified linter
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
STRICT=false
|
|
if [ "${1:-}" = "--strict" ]; then
|
|
STRICT=true
|
|
fi
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
SKIP=0
|
|
|
|
run_tool() {
|
|
local name="$1"
|
|
shift
|
|
echo ""
|
|
echo "─── $name ─────────────────────────────────────"
|
|
if "$@"; then
|
|
echo "✓ $name: PASS"
|
|
PASS=$((PASS+1))
|
|
else
|
|
rc=$?
|
|
if [ $rc -eq 127 ]; then
|
|
echo "⚠ $name: SKIP (not installed)"
|
|
SKIP=$((SKIP+1))
|
|
else
|
|
echo "✗ $name: FAIL (rc=$rc)"
|
|
FAIL=$((FAIL+1))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# gosec: static analysis. REQ-014 baseline is empty (clean repo);
|
|
# any new G101 (hardcoded credentials) fails the build.
|
|
run_gosec() {
|
|
if ! command -v gosec >/dev/null 2>&1; then
|
|
return 127
|
|
fi
|
|
gosec -fmt text -quiet ./...
|
|
}
|
|
|
|
# govulncheck: vulnerability scan. REQ-027: offline mode.
|
|
# We rely on the bundled DB; the `GOVULNCHECK_DB` env var (when
|
|
# present) overrides. This is documented in docs/security-scanning.md.
|
|
run_govulncheck() {
|
|
if ! command -v govulncheck >/dev/null 2>&1; then
|
|
return 127
|
|
fi
|
|
GOFLAGS=-mod=mod govulncheck -mode binary ./... >/dev/null
|
|
}
|
|
|
|
# gitleaks: secret scan. REQ-039 allowlist via .gitleaks.toml;
|
|
# REQ-029 baseline via .gitleaks-baseline.json.
|
|
run_gitleaks() {
|
|
if ! command -v gitleaks >/dev/null 2>&1; then
|
|
return 127
|
|
fi
|
|
if [ ! -f .gitleaks-baseline.json ]; then
|
|
echo " (no .gitleaks-baseline.json; first run will be unfiltered)"
|
|
fi
|
|
gitleaks detect --source . --config .gitleaks.toml --baseline-path .gitleaks-baseline.json --no-banner
|
|
}
|
|
|
|
run_tool "gosec" run_gosec
|
|
run_tool "govulncheck" run_govulncheck
|
|
run_tool "gitleaks" run_gitleaks
|
|
|
|
echo ""
|
|
echo "─── summary ─────────────────────────────────────"
|
|
echo " $PASS pass, $FAIL fail, $SKIP skip"
|
|
echo ""
|
|
|
|
if [ $FAIL -gt 0 ]; then
|
|
echo "✗ security-scan FAILED ($FAIL tool(s) reported findings)"
|
|
exit 1
|
|
fi
|
|
|
|
if $STRICT && [ $SKIP -gt 0 ]; then
|
|
echo "✗ security-scan FAILED in --strict mode ($SKIP tool(s) skipped)"
|
|
exit 2
|
|
fi
|
|
|
|
echo "✓ security-scan PASSED"
|