diff --git a/README.md b/README.md index d8c5d00..f2db708 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,23 @@ marketplaces. Distribution is **copy-paste**: vendor the `scan/` directory plus the relevant wrapper into your repo. A native CodePipeline action provider is an AWS Partner integration; an AWS Marketplace listing is a separate product (container/SaaS) motion. + +## Rule integrity + +`trustabl` verifies rules against an embedded trust keyring by default and +refuses to run unverified rules, exiting 2 on a verification failure. It also +has an unsigned git path, and this plugin exposes two inputs that reach it: + +| Var | Default | Effect on integrity | +|---|---|---| +| `RULES_REPO` | _(default)_ | Exported as `TRUSTABL_RULES_REPO` — points the scan at a different rules source. | +| `RULES_REF` | _(default)_ | Pins a git ref rather than taking the current signed bundle. | +| `REQUIRE_SIGNED` | `false` | `true` passes `--require-signed`, which forbids the unsigned fallback. | + +Neither of the first two is wrong to use — pinning a ref is a reasonable way to +get reproducible scans. What matters is that a gate should be explicit about it. +Set `REQUIRE_SIGNED=true` and the scan fails rather than quietly falling back to +unsigned rules; leave it unset and the behaviour is exactly as before. + +A scanner is only as trustworthy as the rules it runs, so it is worth deciding +this deliberately rather than inheriting a default. diff --git a/scan/trustabl-scan.sh b/scan/trustabl-scan.sh index caa6314..bd46fae 100644 --- a/scan/trustabl-scan.sh +++ b/scan/trustabl-scan.sh @@ -11,7 +11,7 @@ # GitLab-only bits (gl-sast report, CI_* env) are swapped for AWS equivalents. # # Inputs are environment variables (all optional; sensible defaults): -# TARGET VERSION DETECTORS STRICT RULES_REF RULES_REPO +# TARGET VERSION DETECTORS STRICT RULES_REF RULES_REPO REQUIRE_SIGNED # SARIF_FILE JSON_FILE RISK_SCORE_THRESHOLD SEVERITY_THRESHOLD # BRANCH GITHUB_TOKEN DEBUG @@ -132,6 +132,15 @@ BASE_ARGS=(scan "$TARGET") [ -n "$DETECTORS" ] && BASE_ARGS+=(--detectors "$DETECTORS") [ "$STRICT" = "true" ] && BASE_ARGS+=(--strict) [ -n "$RULES_REF" ] && BASE_ARGS+=(--rules-ref "$RULES_REF") +# trustabl verifies rules against an embedded keyring by default and exits 2 on +# a verification failure, but it also has an unsigned git path. This plugin +# hands users two knobs onto that path -- RULES_REPO (exported above as +# TRUSTABL_RULES_REPO) and RULES_REF -- and offered no way to say "never accept +# unsigned rules", which is exactly the guarantee a CI gate wants. +# Matched case-insensitively on purpose: silently ignoring REQUIRE_SIGNED=TRUE +# would be a fail-open on the one input whose job is to tighten the gate. +REQ_SIGNED="${REQUIRE_SIGNED:-false}" +[ "${REQ_SIGNED,,}" = "true" ] && BASE_ARGS+=(--require-signed) # Run 1: SARIF (file emit). trustabl "${BASE_ARGS[@]}" --format sarif > "$SARIF_FILE"