From a958c59269554199cfcfde0e6164ab46727992f6 Mon Sep 17 00:00:00 2001 From: Anuj Hydrabadi Date: Thu, 23 Jul 2026 15:05:18 +0530 Subject: [PATCH] fix: keep raptor's Trivy scan out of terraform-init'd .terraform/ deps raptor's module validation runs terraform init (vendoring remote module dependencies into .terraform/modules/) and then trivy config on the module directory with no --skip-dirs, so HIGH/CRITICAL findings in dependency code the module author never wrote fail CI (e.g. KSV-0041/KSV-0056 against nginx-gateway-fabric's ClusterRole pulled in via facets-utility-modules). Trivy binds every flag to a TRIVY_* env var and raptor runs it as a child process, so exporting TRIVY_SKIP_DIRS on the preview and publish steps scopes the scan to the module's own source without needing a raptor release. Verified with trivy 0.72.0 against a module sourcing facets-utility-modules: baseline reports 4 HIGH/CRITICAL from .terraform/modules/*/nginx_gateway_fabric, with TRIVY_SKIP_DIRS it reports 0, and a seeded misconfiguration in the module's own source is still flagged. Fixes #13 Co-Authored-By: Claude Fable 5 --- module-ci-action/README.md | 4 ++++ module-ci-action/action.yml | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/module-ci-action/README.md b/module-ci-action/README.md index 0473d90..01698b8 100644 --- a/module-ci-action/README.md +++ b/module-ci-action/README.md @@ -187,6 +187,10 @@ Plane. When a PR previews a module, the action registers the preview against the - **Validation gate (preview):** each module is first run through `raptor create iac-module -f --dry-run` (schema + Terraform + security checks) before the feature-branch registration. +- **Security scan scope:** the Trivy scan (run by raptor) covers only the module's own + source. Raptor's validation runs `terraform init` first, which downloads remote module + dependencies into `.terraform/`; the action sets `TRIVY_SKIP_DIRS` so findings inside + those downloaded dependencies — code the module author never wrote — cannot fail CI. - **Provenance:** preview passes the PR head SHA explicitly because the PR checkout is a merge commit; publish relies on auto-detected provenance (on a push the checked-out `HEAD` *is* the pushed commit). The git remote URL is auto-detected from the work tree. diff --git a/module-ci-action/action.yml b/module-ci-action/action.yml index 1de9c79..beb80ed 100644 --- a/module-ci-action/action.yml +++ b/module-ci-action/action.yml @@ -256,6 +256,11 @@ runs: FACETS_USERNAME: ${{ inputs.username }} FACETS_TOKEN: ${{ inputs.token }} PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + # Trivy runs inside raptor's module validation, AFTER terraform init has + # vendored remote deps into .terraform/. Trivy reads flags from TRIVY_* + # env vars; skip the vendored tree so findings in dependency code the + # module author never wrote can't fail CI (issue #13). + TRIVY_SKIP_DIRS: "**/.terraform,**/.terraform/**" run: | set -uo pipefail FAILURES="${RUNNER_TEMP}/ci_failures" @@ -352,6 +357,9 @@ runs: CONTROL_PLANE_URL: ${{ inputs.control_plane_url }} FACETS_USERNAME: ${{ inputs.username }} FACETS_TOKEN: ${{ inputs.token }} + # Same rationale as the preview step: keep raptor's Trivy scan out of + # terraform-init'd dependencies under .terraform/ (issue #13). + TRIVY_SKIP_DIRS: "**/.terraform,**/.terraform/**" run: | set -uo pipefail FAILURES="${RUNNER_TEMP}/ci_failures"