feat(P4): pipeline hardening — Checkov before plan, Wiz-or-Checkov on plan (REQ-250)
Nova Slides Render / render (push) Failing after 1m1s
Nova Slides Render / render (push) Failing after 1m1s
Two-stage policy scan per item 20: 1. Checkov on static code BEFORE terraform plan (fail-fast, quick dev feedback). Added to run_platform.sh Step 3c + run_codegen.sh Step 3c (runs on the authored TF dir before plan, using --framework terraform). 2. Runtime policy scan on the plan AFTER terraform plan: Wiz when configured (WIZ_API_TOKEN + WIZ_API_URL), else Checkov against the plan as a drop-in replacement (--framework terraform_plan). Wiz and Checkov are NEVER both run on the plan. Replaces the old single Checkov-on-main.tf step in run_platform.sh Step 5 + run_postapply.sh Step 5. pipelines/contract.yml: stage list updated — 'checkov' stage replaced by 'checkov-static' (before terraform-plan) + 'runtime-policy-scan' (after terraform-plan). 9 stages → 10 stages. Header comment updated. adapters/wiz/wiz_adapter.py: add --plan mode CLI (fetch_and_adapt_plan) for scanning a terraform plan; backward-compat with the positional <wiz_issues.json> <contract-id> mode. is_configured() gates the Wiz path. Tests: test_pipeline_contract.py (9 → 10 stages, new stage names); test_contract_resolver.py (rename test, assert checkov-static + runtime-policy-scan present, old 'checkov' gone). Full suite: 685 pass + 1 pre-existing attestation failure (NOVA_ATTESTATION_SIGNING_KEY_ID unset, unrelated to v1.21, fails on main without these changes too). ---ci--- project: acdl phase: 4 milestone: v1.21 status: execute phase_role: execution ---/ci---
This commit is contained in:
+43
-12
@@ -312,6 +312,20 @@ if [ -z "${AWS_ACCESS_KEY_ID:-}" ] || [ -z "${AWS_SECRET_ACCESS_KEY:-}" ]; then
|
||||
export AWS_DEFAULT_REGION="$AWS_DEFAULT_REGION"
|
||||
fi
|
||||
|
||||
echo "=== Step 3c: Checkov on static code (fail-fast, before terraform plan) ==="
|
||||
# REQ-250 (v1.21): Checkov runs on the authored Terraform code BEFORE
|
||||
# terraform plan so developers get immediate policy feedback, not a
|
||||
# delayed plan-stage failure. The runtime plan scan (Wiz-or-Checkov)
|
||||
# runs after the plan (Step 5).
|
||||
if [ "$QUIET" = "0" ]; then
|
||||
checkov -d "$TF_DIR" --framework terraform -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ 2>&1 | tee "$WORK/checkov-static.json"
|
||||
else
|
||||
checkov -d "$TF_DIR" --framework terraform -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ > "$WORK/checkov-static.json" 2> "$WORK/checkov-static.err"
|
||||
fi
|
||||
[ -s "$WORK/checkov-static.json" ] || fail "checkov (static) produced no output"
|
||||
echo ""
|
||||
echo "checkov (static) summary: $(python3 -c "import json; d=json.load(open('$WORK/checkov-static.json')); print(len(d.get('results',{}).get('failed_checks',[])), 'failed,', len(d.get('results',{}).get('passed_checks',[])), 'passed')")"
|
||||
|
||||
echo "=== Step 4: terraform init + validate + plan -lock=false (real AWS) ==="
|
||||
cd "$TF_DIR"
|
||||
|
||||
@@ -380,19 +394,36 @@ if [ "$DESTROY_ONLY" = "1" ]; then
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Step 5: run Checkov on $TF_DIR/main.tf ==="
|
||||
if [ "$QUIET" = "0" ]; then
|
||||
checkov -f "$TF_DIR/main.tf" --framework terraform -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ 2>&1 | tee "$WORK/checkov.json"
|
||||
echo "=== Step 5: runtime policy scan on the terraform plan (Wiz-or-Checkov, never both) ==="
|
||||
# REQ-250 (v1.21): after terraform plan, run Wiz against the plan when
|
||||
# configured; otherwise run Checkov against the plan as a drop-in
|
||||
# replacement. Wiz and Checkov are NEVER both run on the plan.
|
||||
RUNTIME_SCAN_ENGINE=""
|
||||
if [ -n "${WIZ_API_TOKEN:-}" ] || [ -n "${WIZ_API_URL:-}" ]; then
|
||||
RUNTIME_SCAN_ENGINE="wiz"
|
||||
echo "--- Wiz configured (WIZ_API_TOKEN + WIZ_API_URL) → Wiz on the plan ---"
|
||||
python3 adapters/wiz/wiz_adapter.py --plan "$TF_DIR/tfplan" --contract-id "$CONTRACT_ID" --run-id "${CONTRACT_ID}" > "$WORK/pcr.json" 2> "$WORK/wiz.err" || {
|
||||
echo "WARNING: Wiz scan failed; falling back to Checkov on the plan" >&2
|
||||
RUNTIME_SCAN_ENGINE="checkov-plan"
|
||||
}
|
||||
else
|
||||
checkov -f "$TF_DIR/main.tf" --framework terraform -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ > "$WORK/checkov.json" 2> "$WORK/checkov.err"
|
||||
RUNTIME_SCAN_ENGINE="checkov-plan"
|
||||
fi
|
||||
[ -s "$WORK/checkov.json" ] || fail "checkov produced no output"
|
||||
echo ""
|
||||
echo "checkov summary: $(python3 -c "import json; d=json.load(open('$WORK/checkov.json')); print(len(d.get('results',{}).get('failed_checks',[])), 'failed,', len(d.get('results',{}).get('passed_checks',[])), 'passed')")"
|
||||
|
||||
echo ""
|
||||
echo "=== Step 6: Checkov adapter -> PolicyCheckResult (compliance details) ==="
|
||||
python3 adapters/terraform/policy/checkov_adapter.py "$WORK/checkov.json" "$CONTRACT_ID" > "$WORK/pcr.json" || fail "checkov adapter failed"
|
||||
if [ "$RUNTIME_SCAN_ENGINE" = "checkov-plan" ]; then
|
||||
echo "--- Wiz not configured → Checkov on the plan (drop-in replacement) ---"
|
||||
if [ "$QUIET" = "0" ]; then
|
||||
checkov -f "$TF_DIR/tfplan" --framework terraform_plan -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ 2>&1 | tee "$WORK/checkov-plan.json"
|
||||
else
|
||||
checkov -f "$TF_DIR/tfplan" --framework terraform_plan -o json --soft-fail --external-checks-dir adapters/terraform/policy/custom_rules/ > "$WORK/checkov-plan.json" 2> "$WORK/checkov-plan.err"
|
||||
fi
|
||||
[ -s "$WORK/checkov-plan.json" ] || fail "checkov (plan) produced no output"
|
||||
echo ""
|
||||
echo "checkov (plan) summary: $(python3 -c "import json; d=json.load(open('$WORK/checkov-plan.json')); print(len(d.get('results',{}).get('failed_checks',[])), 'failed,', len(d.get('results',{}).get('passed_checks',[])), 'passed')")"
|
||||
echo ""
|
||||
echo "=== Step 6: Checkov (plan) adapter -> PolicyCheckResult ==="
|
||||
python3 adapters/terraform/policy/checkov_adapter.py "$WORK/checkov-plan.json" "$CONTRACT_ID" > "$WORK/pcr.json" || fail "checkov (plan) adapter failed"
|
||||
fi
|
||||
echo "runtime scan engine: $RUNTIME_SCAN_ENGINE"
|
||||
python3 -c "
|
||||
import json
|
||||
pcrs = json.load(open('$WORK/pcr.json'))
|
||||
@@ -494,5 +525,5 @@ source "$ROOT/scripts/run_uptime.sh"
|
||||
|
||||
echo ""
|
||||
echo "=== PLATFORM E2E OK ==="
|
||||
echo "contract -> resolver -> stack -> terraform plan -> Checkov -> confidence ($BAND) -> outbox -> outputs"
|
||||
echo "contract -> resolver -> stack -> Checkov(static) -> terraform plan -> Wiz-or-Checkov(plan) -> confidence ($BAND) -> outbox -> outputs"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user