Skip to content

security(trivy): declare the trusted registries so KSV-0125 gates instead of noises - #3216

Merged
devantler merged 2 commits into
mainfrom
claude/checkov-k8s-disposition-2787-2
Aug 18, 2026
Merged

devantler merged 2 commits into
mainfrom
claude/checkov-k8s-disposition-2787-2

Conversation

@devantler

@devantler devantler commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

Our container-image security check was switched on but effectively blind. Trivy ships trusting only Amazon, Google and Microsoft registries — and we use none of them — so it reported every single container we run as coming from an untrusted registry. That is 27 findings that told us nothing except "this is not an AWS shop", and it is a large part of why this scanner is still parked as non-blocking.

A check that always fails is a check nobody can act on. If someone added a workload pulling from a registry we do not trust, today it would look exactly like the 27 findings already there.

What

Declares the four registries we actually pull from, so the check compares against our real supply chain instead of a cloud vendor default. It now passes on what we legitimately use and stands out on anything else.

One image was also written ambiguously enough that the check misread where it came from; it is now written in full, pointing at the same pinned image as before.

It also records a way of measuring this backlog that quietly gives the wrong answer: checking only the Kubernetes folder rather than the whole repository doubles the reported number, because the exemptions we have already agreed stop applying. That reads as more work to do rather than as a broken measurement, so the warning now sits next to the instructions.

Security floor gained: an image from an unexpected registry is now a visible finding rather than being lost in permanent noise.
Everyday cost: none — no new step for anyone. Adding a registry later is one reviewed line in a documented file. The scanner backlog on this tree drops by roughly a third (93 → 66 findings, 29 → 16 affected files), which makes the remaining work easier to see.

This is one slice of a larger backlog, not the whole of it — the scanner stays non-blocking until the rest is worked off.

Part of #2787

…tead of noises

KSV-0125 ("Restrict container images to trusted registries") ships a default
trusted list of Azure ACR, AWS ECR and GCR only — read from the check's own
rego, not inferred. This repository uses none of those three, so the check
flagged every container it declares: 27 findings, the single largest family on
this tree, none of which said anything about supply-chain risk.

Declare the four registries actually in use (derived from the tree: quay.io,
docker.io, registry.k8s.io, ghcr.io) via --config-data. The check reads
data.ksv0125.trusted_registries and uses it instead of its defaults, which turns
a permanently-failing check into one that can catch an unexpected registry.

The check proved it still discriminates by surviving on one container:
vault-config's store-keys ran `alpine/k8s`, whose first path segment is a Docker
Hub namespace rather than a registry host, so the check read the registry as
"alpine". Fixed at the manifest by writing it fully-qualified with the same
pinned digest, matching the 11 docker.io images already written that way.

Measured with scripts/megalinter-scan-counts.sh: trivy 93 -> 66 across 29 -> 16
targets; checkov unchanged at 0. Ablation: deleting the single quay.io entry
returns exactly 11 findings, all quay.io-hosted, so the list is load-bearing.

Part of #2787
@github-actions

github-actions Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

✅⚠️MegaLinter analysis: Success with warnings

⚠️ BASH / bash-exec - 4 errors
Results of bash-exec linter (version 5.3.9)
See documentation on https://megalinter.io/10.0.0/descriptors/bash_bash_exec/
-----------------------------------------------

✅ [SUCCESS] .github/scripts/setup-ksail.sh
✅ [SUCCESS] scripts/check-megalinter-version-drift.sh
✅ [SUCCESS] scripts/dr-rebuild-supersession-guard.sh
❌ [ERROR] scripts/ghcr-auth-lib.sh
    Error: File:[scripts/ghcr-auth-lib.sh] is not executable

✅ [SUCCESS] scripts/guard-cilium-homogeneous-device-rollout.sh
✅ [SUCCESS] scripts/guard-kubescape-gate-frameworks.sh
✅ [SUCCESS] scripts/guard-shared-publish-workflow-pin.sh
✅ [SUCCESS] scripts/megalinter-scan-counts.sh
✅ [SUCCESS] scripts/normalize-sarif-paths.sh
❌ [ERROR] scripts/refresh-flux-ghcr-auth-safety.sh
    Error: File:[scripts/refresh-flux-ghcr-auth-safety.sh] is not executable

✅ [SUCCESS] scripts/refresh-flux-ghcr-auth.sh
✅ [SUCCESS] scripts/report-cilium-rollout-gate-suppression.sh
✅ [SUCCESS] scripts/run-ksail-prod-with-pull-auth.sh
✅ [SUCCESS] scripts/summarize-sarif-findings.sh
✅ [SUCCESS] scripts/tests/test-actual-budget-auth-route.sh
✅ [SUCCESS] scripts/tests/test-check-megalinter-version-drift.sh
✅ [SUCCESS] scripts/tests/test-cilium-bandwidth-manager-component.sh
✅ [SUCCESS] scripts/tests/test-cilium-homogeneous-devices-activation.sh
✅ [SUCCESS] scripts/tests/test-cilium-homogeneous-devices-autoscaler-gate.sh
✅ [SUCCESS] scripts/tests/test-cilium-homogeneous-devices-flux-wait.sh
✅ [SUCCESS] scripts/tests/test-cilium-mutual-auth-policy-regressions.sh
✅ [SUCCESS] scripts/tests/test-cilium-mutual-auth-policy.sh
✅ [SUCCESS] scripts/tests/test-cilium-rollout-gate-suppression-signal.sh
✅ [SUCCESS] scripts/tests/test-cnpg-degraded-alert.sh
✅ [SUCCESS] scripts/tests/test-coroot-postgres-scrape-policy.sh
✅ [SUCCESS] scripts/tests/test-crossplane-egress-policy.sh
✅ [SUCCESS] scripts/tests/test-crossplane-sync-exporter.sh
✅ [SUCCESS] scripts/tests/test-dr-rebuild-supersession-guard.sh
✅ [SUCCESS] scripts/tests/test-github-config-role-activation-parity.sh
❌ [ERROR] scripts/tests/test-headlamp-plugin-removal.sh
    Error: File:[scripts/tests/test-headlamp-plugin-removal.sh] is not executable

✅ [SUCCESS] scripts/tests/test-kubescape-gate-frameworks-guard.sh
✅ [SUCCESS] scripts/tests/test-kyverno-admission-vpa.sh
❌ [ERROR] scripts/tests/test-kyverno-umami-mutation-rbac.sh
    Error: File:[scripts/tests/test-kyverno-umami-mutation-rbac.sh] is not executable

✅ [SUCCESS] scripts/tests/test-megalinter-scan-counts-ignorefile.sh
✅ [SUCCESS] scripts/tests/test-normalize-sarif-paths.sh
✅ [SUCCESS] scripts/tests/test-openbao-oidc-role.sh
✅ [SUCCESS] scripts/tests/test-opencost-usage-scraper.sh
✅ [SUCCESS] scripts/tests/test-pvc-prune-safety.sh
✅ [SUCCESS] scripts/tests/test-refresh-flux-ghcr-auth-safety.sh
✅ [SUCCESS] scripts/tests/test-restrict-homepage-service-groups.sh
✅ [SUCCESS] scripts/tests/test-restrict-tenant-secret-stores.sh
✅ [SUCCESS] scripts/tests/test-setup-ksail.sh
✅ [SUCCESS] scripts/tests/test-shared-publish-workflow-pin-guard.sh
✅ [SUCCESS] scripts/tests/test-summarize-sarif-findings.sh
✅ [SUCCESS] scripts/tests/test-tenant-route-hostname-boundary.sh
✅ [SUCCESS] scripts/tests/test-trivyignore-vendored-operator-boundary.sh
✅ [SUCCESS] scripts/tests/test-umami-provisioning-bootstrap.sh
✅ [SUCCESS] scripts/tests/test-use-prod-stable-api-endpoint.sh
✅ [SUCCESS] scripts/tests/test-validate-image-verifier-liveness.sh
✅ [SUCCESS] scripts/tests/test-verify-published-evidence.sh
✅ [SUCCESS] scripts/update-vendored-operators.sh
✅ [SUCCESS] scripts/use-prod-stable-api-endpoint.sh
✅ [SUCCESS] scripts/validate-alert-coverage.sh
✅ [SUCCESS] scripts/validate-image-verifier-liveness.sh
✅ [SUCCESS] scripts/verify-published-evidence.sh
✅ [SUCCESS] scripts/wait-for-platform-flux-revision.sh
⚠️ SPELL / cspell - 3659 errors
"ifnotpresent",
        "ignorefile",
        "imagevalidatingpolicy",
        "imranismail",
        "initprovider",
        "injective",
        "inspectable",
        "iscsi",
        "italicise",
        "ivpol",
        "jobif",
        "journalled",
        "keylessly",
        "keypair",
        "kprobes",
        "kptr",
        "krew",
        "ksail",
        "ksail's",
        "ksailcd",
        "kubeconfig",
        "kubeconfig's",
        "kubeconform",
        "kubeconform's",
        "kubelet",
        "kubelet's",
        "kubelets",
        "kubescape",
        "kubescape's",
        "kubespan",
        "kubevirt",
        "kubevuln",
        "kustomization",
        "kustomizations",
        "letsencrypt",
        "libc",
        "libgnutls",
        "lintable",
        "livez",
        "loadtester",
        "locationless",
        "logfile",
        "lookarounds",
        "lrwxrwxrwx",
        "lserror",
        "lsfail",
        "luks",
        "lycheeignore",
        "machineconfig",
        "materialise",
        "materialised",
        "materialises",
        "maxage",
        "maxbackup",
        "maxsize",
        "maxx",
        "microtime",
        "mikefarah",
        "misconfig",
        "misconfigs",
        "misordered",
        "mistargeted",
        "mitrelike",
        "mktemp",
        "mlock",
        "mutatingpolicies",
        "mutatingwebhookconfigurations",
        "myapp",
        "najsk",
        "neighbour",
        "nenv",
        "netlink",
        "netpol",
        "netpols",
        "neutralises",
        "neutralising",
        "nextjs",
        "nftables",
        "nilnil",
        "nobuckets",
        "nodepod",
        "nodeport",
        "nolabel",
        "nolint",
        "nonexec",
        "nonroot",
        "normalisation",
        "normalise",
        "normalised",
        "normalises",
        "normalising",
        "nosec",
        "nsalike",
        "nullglob",
        "ocirepository",
        "onlycri",
        "onlysystem",
        "openbao",
        "opencost",
        "openfeature",
        "oras",
        "otherplugin",
        "overclaimed",
        "overprovisioning",
        "parallelised",
        "partialgroup",
        "pasteable",
        "permissioning",
        "persistentvolumeclaims",
        "phaseless",
        "pipefail",
        "policyreports",
        "portforward",
        "preemptible",
        "preservingly",
        "prioritisable",
        "prioritisation",
        "prioritised",
        "privesc",
        "probeerror",
        "providerconfigs",
        "pseudonymization",
        "pseudonymized",
        "pseudonymizes",
        "publishapp",
        "publishprovider",
        "pushsecret",
        "pushsecrets",
        "qrbvrml",
        "randomises",
        "rdqwpktr",
        "readyz",
        "reassertions",
        "recognisable",
        "recognisably",
        "recognise",
        "recognised",
        "recolour",
        "reconverges",
        "referencegrants",
        "refreshfluxghcrauth",
        "regenerable",
        "rego",
        "releaserc",
        "rematerialise",
        "rematerialised",
        "replicaset",
        "repoint",
        "repointed",
        "repoints",
        "repositoryrulesets",
        "resizer",
        "restrictor",
        "retabbed",
        "retarget",
        "rmem",
        "rolebindings",
        "rollouts",
        "rshared",
        "rwxr",
        "sanitised",
        "sanitiser",
        "sanitising",
        "sarif",
        "scheckov",
        "schedulability",
        "schedulable",
        "scopeable",
        "scopeless",
        "seccomp",
        "secretbox",
        "secretstore",
        "seedable",
        "serialise",
        "serialised",
        "serverside",
        "serviceaccount",
        "serviceaccounts",
        "sgdisk",
        "shellcheck",
        "shfmt",
        "shopt",
        "shortsha",
        "siderolabs",
        "siderolink",
        "sigstore",
        "skmde",
        "slurpfile",
        "sngle",
        "specnull",
        "spiffe",
        "sprintf",
        "srole",
        "stakater",
        "startswith",
        "statefulset",
        "statemanager",
        "stdlib",
        "stepif",
        "storageclass",
        "strenv",
        "subshell",
        "subtest",
        "summarised",
        "surfaceless",
        "syft",
        "syscall",
        "sysctls",
        "syste",
        "systembare",
        "tagliteral",
        "tagonly",
        "talosconfig",
        "talosctl",
        "tanzu",
        "tcproutes",
        "teammemberships",
        "teamrepositories",
        "templatesyncignore",
        "thresholded",
        "tlsroutes",
        "tlsv",
        "tmpl",
        "toplevel",
        "tostring",
        "tracepoints",
        "travelled",
        "trixie",
        "trueish",
        "trustd",
        "ture",
        "udproutes",
        "uids",
        "umami",
        "umami's",
        "unablated",
        "unclickable",
        "uncompilable",
        "unconfigured",
        "uncordon",
        "uncordoned",
        "uncordoning",
        "uncordons",
        "undecoded",
        "undercounts",
        "undispositioned",
        "unenforcing",
        "unevidenced",
        "unexcepted",
        "unfiled",
        "ungated",
        "ungenerated",
        "unifi",
        "uninspected",
        "uninvoked",
        "unioned",
        "unmarshalling",
        "unmarshals",
        "unmodelled",
        "unparseable",
        "unprovisioned",
        "unrecognisable",
        "unrecognised",
        "unrepresentable",
        "unreviewed",
        "unroutable",
        "unrun",
        "unshippable",
        "unskipped",
        "untrackable",
        "unvalidated",
        "unwaited",
        "unwired",
        "upbound",
        "updatekeys",
        "upjet",
        "upstreaming",
        "urlencode",
        "userinfo",
        "userns",
        "ushfn",
        "validatable",
        "validatealertcoverage",
        "validatingwebhookconfigurations",
        "vcunav",
        "velero",
        "virt",
        "volumesnapshot",
        "vpas",
        "vulnerabilitymanifests",
        "vulnerabilitymanifestsummary",
        "vulns",
        "vxlan",
        "wffc",
        "wgpolicyk",
        "wildcarded",
        "wlid",
        "wmem",
        "workloadconfigurationscans",
        "workloadconfigurationscansummary",
        "worktrees",
        "xpkg",
        "yannh",
        "yubikey",
        "yzwvjjmcyfnl",
        "zizmor"
    ]
}


You can also copy-paste megalinter-reports/.cspell.json at the root of your repository

(Truncated to last 6666 characters out of 660305)
⚠️ COPYPASTE / jscpd - 147 errors
ts/test-crossplane-egress-policy.sh [260:25 - 268:19] (9 lines, 52 tokens)
   scripts/tests/test-crossplane-egress-policy.sh [280:24 - 288:19]
Clone found (bash)
 - scripts/tests/test-crossplane-egress-policy.sh [260:25 - 268:18] (9 lines, 51 tokens)
   scripts/tests/test-crossplane-egress-policy.sh [305:31 - 313:18]
Clone found (bash)
 - scripts/tests/test-crossplane-egress-policy.sh [291:13 - 299:8] (9 lines, 52 tokens)
   scripts/tests/test-crossplane-egress-policy.sh [370:18 - 378:14]
Clone found (bash)
 - scripts/tests/test-crossplane-egress-policy.sh [369:22 - 378:15] (10 lines, 63 tokens)
   scripts/tests/test-crossplane-egress-policy.sh [379:33 - 388:15]
Clone found (bash)
 - scripts/tests/test-crossplane-sync-exporter.sh [186:1 - 235:2] (50 lines, 299 tokens)
   scripts/tests/test-kyverno-umami-mutation-rbac.sh [16:1 - 63:2]
Clone found (bash)
 - scripts/tests/test-crossplane-sync-exporter.sh [186:1 - 237:11] (52 lines, 303 tokens)
   scripts/tests/test-opencost-usage-scraper.sh [33:1 - 84:11]
Clone found (bash)
 - scripts/tests/test-crossplane-sync-exporter.sh [221:27 - 238:53] (18 lines, 53 tokens)
   scripts/tests/test-opencost-usage-scraper.sh [68:27 - 85:51]
Clone found (bash)
 - scripts/tests/test-headlamp-plugin-removal.sh [121:89 - 126:22] (6 lines, 65 tokens)
   scripts/tests/test-headlamp-plugin-removal.sh [165:84 - 170:22]
Clone found (bash)
 - scripts/tests/test-refresh-flux-ghcr-auth-safety.sh [348:5 - 356:51] (9 lines, 76 tokens)
   scripts/tests/test-refresh-flux-ghcr-auth-safety.sh [357:5 - 365:51]
Clone found (python)
 - scripts/tests/test_validate_homepage_bookmarks.py [46:57 - 54:54] (9 lines, 58 tokens)
   scripts/tests/test_validate_homepage_bookmarks.py [100:53 - 109:54]
Clone found (go)
 - scripts/validate-dr-signing/main_test.go [1007:13 - 1015:2] (9 lines, 51 tokens)
   scripts/validate-dr-signing/main_test.go [1075:12 - 1083:2]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [564:50 - 569:24] (6 lines, 103 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1076:31 - 1081:24]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [596:14 - 602:4] (7 lines, 115 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [923:43 - 929:4]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [622:13 - 631:7] (10 lines, 158 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1205:18 - 1214:7]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [631:1 - 636:8] (6 lines, 93 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1215:1 - 1220:8]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [708:5 - 713:2] (6 lines, 82 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [894:8 - 899:9]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [709:1 - 719:23] (11 lines, 220 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [986:60 - 997:3]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [713:15 - 724:2] (12 lines, 185 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [814:17 - 825:2]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [760:15 - 771:12] (12 lines, 264 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [969:1 - 982:3]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [823:2 - 829:19] (7 lines, 89 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1008:7 - 1014:19]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [823:2 - 829:33] (7 lines, 103 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1390:58 - 1396:33]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [823:2 - 829:4] (7 lines, 74 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1503:5 - 1509:4]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [916:30 - 921:8] (6 lines, 50 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [943:44 - 948:8]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [1030:22 - 1036:2] (7 lines, 135 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1589:22 - 1595:2]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [1328:33 - 1336:11] (9 lines, 118 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1340:130 - 1348:11]
Clone found (go)
 - scripts/validate-eks-ci-role-policy/main_test.go [1535:47 - 1540:2] (6 lines, 166 tokens)
   scripts/validate-eks-ci-role-policy/main_test.go [1615:46 - 1620:2]
Clone found (go)
 - scripts/validate-flux-verify/instance_test.go [109:62 - 126:31] (18 lines, 57 tokens)
   scripts/validate-flux-verify/instance_test.go [161:57 - 178:31]
Clone found (go)
 - scripts/validate-flux-verify/instance_test.go [109:62 - 128:35] (20 lines, 62 tokens)
   scripts/validate-flux-verify/instance_test.go [198:55 - 217:26]
Clone found (python)
 - scripts/validate-naming.py [126:52 - 132:25] (7 lines, 53 tokens)
   scripts/validate-naming.py [171:82 - 177:29]
┌────────┬────────────────┬─────────────┬──────────────┬──────────────┬──────────────────┬───────────────────┐
│ Format │ Files analyzed │ Total lines │ Total tokens │ Clones found │ Duplicated lines │ Duplicated tokens │
├────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ bash   │ 56             │ 18653       │ 73188        │ 36           │ 490 (2.63%)      │ 3377 (4.61%)      │
├────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ go     │ 38             │ 33072       │ 195711       │ 109          │ 890 (2.69%)      │ 8272 (4.23%)      │
├────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ python │ 4              │ 807         │ 5606         │ 2            │ 14 (1.73%)       │ 111 (1.98%)       │
├────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ txt    │ 1              │ 220         │ 1230         │ 0            │ 0 (0.00%)        │ 0 (0.00%)         │
├────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ Total: │ 99             │ 52752       │ 275735       │ 147          │ 1394 (2.64%)     │ 11760 (4.26%)     │
└────────┴────────────────┴─────────────┴──────────────┴──────────────┴──────────────────┴───────────────────┘
Found 147 clones.
HTML report saved to megalinter-reports/copy-paste/jscpd-report.html
ERROR: jscpd found too many duplicates (2.6%) over threshold (0.0%)
time: 1.05s

(Truncated to last 6666 characters out of 28061)
⚠️ SPELL / lychee - 1 error
📝 Summary
---------------------
🔍 Total..........250
🔗 Unique.........161
✅ Successful.....220
⏳ Timeouts.........0
🔀 Redirected.......8
👻 Excluded........29
❓ Unknown..........0
🚫 Errors...........1
⛔ Unsupported......1

Errors in talos/cluster/gc-terminated-pods-sooner.yaml
[ERROR] https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-garbage-collection (at 24:14) | Connection failed. Check network connectivity and firewall settings

Hint: Followed 8 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
⚠️ MARKDOWN / markdownlint - 65 errors
length Line length [Expected: 400; Actual: 439]
AGENTS.md:105:401 error MD013/line-length Line length [Expected: 400; Actual: 1126]
AGENTS.md:106:401 error MD013/line-length Line length [Expected: 400; Actual: 628]
AGENTS.md:107:401 error MD013/line-length Line length [Expected: 400; Actual: 1774]
AGENTS.md:160:401 error MD013/line-length Line length [Expected: 400; Actual: 649]
AGENTS.md:162:401 error MD013/line-length Line length [Expected: 400; Actual: 971]
AGENTS.md:189:401 error MD013/line-length Line length [Expected: 400; Actual: 970]
AGENTS.md:193:401 error MD013/line-length Line length [Expected: 400; Actual: 660]
AGENTS.md:211:401 error MD013/line-length Line length [Expected: 400; Actual: 1510]
AGENTS.md:279:401 error MD013/line-length Line length [Expected: 400; Actual: 1016]
AGENTS.md:280:401 error MD013/line-length Line length [Expected: 400; Actual: 491]
AGENTS.md:281:401 error MD013/line-length Line length [Expected: 400; Actual: 468]
AGENTS.md:287:401 error MD013/line-length Line length [Expected: 400; Actual: 532]
AGENTS.md:289:401 error MD013/line-length Line length [Expected: 400; Actual: 523]
AGENTS.md:292:401 error MD013/line-length Line length [Expected: 400; Actual: 613]
AGENTS.md:293:401 error MD013/line-length Line length [Expected: 400; Actual: 714]
AGENTS.md:297:401 error MD013/line-length Line length [Expected: 400; Actual: 502]
AGENTS.md:301:401 error MD013/line-length Line length [Expected: 400; Actual: 441]
AGENTS.md:306:401 error MD013/line-length Line length [Expected: 400; Actual: 427]
AGENTS.md:409:401 error MD013/line-length Line length [Expected: 400; Actual: 1139]
AGENTS.md:411:401 error MD013/line-length Line length [Expected: 400; Actual: 1240]
AGENTS.md:427:401 error MD013/line-length Line length [Expected: 400; Actual: 1137]
AGENTS.md:824:401 error MD013/line-length Line length [Expected: 400; Actual: 790]
AGENTS.md:829:401 error MD013/line-length Line length [Expected: 400; Actual: 515]
CLAUDE.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "@AGENTS.md"]
docs/dr/alerting.md:226:28 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:22:389 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:23:264 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:27:35 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:27:161 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:27:239 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/crypto-custody.md:114 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Custody recommendations"]
docs/dr/crypto-custody.md:245 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Custody recommendations"]
docs/dr/crypto-custody.md:251 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "What to do if it leaks"]
docs/dr/crypto-custody.md:258 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "What to do if it is *lost* (no..."]
docs/dr/restore-drill.md:42 error MD028/no-blanks-blockquote Blank line inside blockquote
docs/dr/runbook.md:23:102 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/runbook.md:23:487 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/runbook.md:34 error MD028/no-blanks-blockquote Blank line inside blockquote
docs/dr/runbook.md:41 error MD028/no-blanks-blockquote Blank line inside blockquote
docs/dr/runbook.md:50 error MD028/no-blanks-blockquote Blank line inside blockquote
docs/dr/runbook.md:589:92 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/spire-server-ha.md:93 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/dr/velero-cnpg.md:11 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/dr/velero-cnpg.md:56:78 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/velero-cnpg.md:56:166 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/velero-cnpg.md:57:78 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/velero-cnpg.md:57:227 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/velero-cnpg.md:58:78 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/dr/velero-cnpg.md:58:166 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
docs/github-management.md:38:401 error MD013/line-length Line length [Expected: 400; Actual: 419]
docs/github-management.md:40:401 error MD013/line-length Line length [Expected: 400; Actual: 522]
docs/node-autoscaling.md:14 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/oidc-kubectl.md:95 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/runtime-security.md:114 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/rwx-storage.md:9 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/unifi-management.md:14 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/unifi-management.md:62 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
README.md:116:401 error MD013/line-length Line length [Expected: 400; Actual: 540]
README.md:237:32 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]
README.md:237:36 error MD060/table-column-style Table column style [Table pipe does not align with header for style "aligned"]

(Truncated to last 6666 characters out of 7160)
⚠️ REPOSITORY / trivy - 1 error
47
 435 │           securityContext:
 436 │             allowPrivilegeEscalation: false
 437 │             readOnlyRootFilesystem: true
 438 │             runAsNonRoot: true
 439 │             capabilities:
 440 │               drop:
 441 └                 - ALL
 ...   
────────────────────────────────────────


KSV-0021 (LOW): Container 'vault-config' of Job 'vault-config' should set 'securityContext.runAsGroup' > 10000
════════════════════════════════════════
Force the container to run with group ID > 10000 to avoid conflicts with the host’s user table.

See https://avd.aquasec.com/misconfig/ksv-0021
────────────────────────────────────────
 k8s/bases/infrastructure/vault-config/job.yaml:473-512
────────────────────────────────────────
 473 ┌         - name: vault-config
 474 │           image: quay.io/openbao/openbao:2.5.3@sha256:fdc6da21ca6963560c32336fd7feb9cf2d5e52668f1a1647205a4b41171f0806
 475 │           securityContext:
 476 │             # The openbao image's own baked `openbao` user (openbao:x:100:1000
 477 │             # in its /etc/passwd) — see the checkov.io/skip2 rationale.
 478 │             runAsUser: 100
 479 │             allowPrivilegeEscalation: false
 480 │             readOnlyRootFilesystem: true
 481 └             runAsNonRoot: true
 ...   
────────────────────────────────────────


KSV-0021 (LOW): Container 'vault-init' of Job 'vault-config' should set 'securityContext.runAsGroup' > 10000
════════════════════════════════════════
Force the container to run with group ID > 10000 to avoid conflicts with the host’s user table.

See https://avd.aquasec.com/misconfig/ksv-0021
────────────────────────────────────────
 k8s/bases/infrastructure/vault-config/job.yaml:202-240
────────────────────────────────────────
 202 ┌         - name: vault-init
 203 │           image: quay.io/openbao/openbao:2.5.3@sha256:fdc6da21ca6963560c32336fd7feb9cf2d5e52668f1a1647205a4b41171f0806
 204 │           securityContext:
 205 │             # The openbao image's own baked `openbao` user (openbao:x:100:1000
 206 │             # in its /etc/passwd) — see the checkov.io/skip2 rationale.
 207 │             runAsUser: 100
 208 │             allowPrivilegeEscalation: false
 209 │             readOnlyRootFilesystem: true
 210 └             runAsNonRoot: true
 ...   
────────────────────────────────────────



k8s/bases/infrastructure/vault-config/role.yaml (kubernetes)
============================================================
Tests: 117 (SUCCESSES: 115, FAILURES: 2)
Failures: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 0, CRITICAL: 0)

KSV-0113 (MEDIUM): Role 'vault-config' shouldn't have access to manage secrets in namespace 'openbao'
════════════════════════════════════════
Viewing secrets at the namespace scope can lead to escalation if another service account in that namespace has a higher privileged rolebinding or clusterrolebinding bound.

See https://avd.aquasec.com/misconfig/ksv-0113
────────────────────────────────────────
 k8s/bases/infrastructure/vault-config/role.yaml:11-13
────────────────────────────────────────
  11 ┌   - apiGroups: [""]
  12 │     resources: ["secrets"]
  13 └     verbs: ["create"]
────────────────────────────────────────


KSV-0113 (MEDIUM): Role 'vault-config' shouldn't have access to manage secrets in namespace 'openbao'
════════════════════════════════════════
Viewing secrets at the namespace scope can lead to escalation if another service account in that namespace has a higher privileged rolebinding or clusterrolebinding bound.

See https://avd.aquasec.com/misconfig/ksv-0113
────────────────────────────────────────
 k8s/bases/infrastructure/vault-config/role.yaml:14-17
────────────────────────────────────────
  14 ┌   - apiGroups: [""]
  15 │     resources: ["secrets"]
  16 │     verbs: ["get", "update", "patch"]
  17 └     resourceNames: ["openbao-unseal"]
────────────────────────────────────────



k8s/clusters/local/bootstrap/config-map.yaml (kubernetes)
=========================================================
Tests: 117 (SUCCESSES: 116, FAILURES: 1)
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)

KSV-01010 (MEDIUM): ConfigMap 'variables-cluster' in 'flux-system' namespace stores sensitive contents in key(s) or value(s) '{"admin_email"}'
════════════════════════════════════════
Storing sensitive content such as usernames and email addresses in configMaps is unsafe

See https://avd.aquasec.com/misconfig/ksv-01010
────────────────────────────────────────
 k8s/clusters/local/bootstrap/config-map.yaml:1
────────────────────────────────────────
   1 [ ---
────────────────────────────────────────



k8s/clusters/prod/bootstrap/config-map.yaml (kubernetes)
========================================================
Tests: 116 (SUCCESSES: 115, FAILURES: 1)
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)

KSV-01010 (MEDIUM): ConfigMap 'variables-cluster' in 'flux-system' namespace stores sensitive contents in key(s) or value(s) '{"admin_email"}'
════════════════════════════════════════
Storing sensitive content such as usernames and email addresses in configMaps is unsafe

See https://avd.aquasec.com/misconfig/ksv-01010
────────────────────────────────────────
 k8s/clusters/prod/bootstrap/config-map.yaml:1
────────────────────────────────────────
   1 [ ---
────────────────────────────────────────



k8s/providers/docker/infrastructure/controllers/coredns/deployment.yaml (kubernetes)
====================================================================================
Tests: 114 (SUCCESSES: 113, FAILURES: 1)
Failures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

KSV-0011 (LOW): Container 'coredns' of Deployment 'coredns' should set 'resources.limits.cpu'
════════════════════════════════════════
Enforcing CPU limits prevents DoS via resource exhaustion.

See https://avd.aquasec.com/misconfig/ksv-0011
────────────────────────────────────────
 k8s/providers/docker/infrastructure/controllers/coredns/deployment.yaml:67-121
────────────────────────────────────────
  67 ┌         - args:
  68 │             - -conf
  69 │             - /etc/coredns/Corefile
  70 │           image: registry.k8s.io/coredns/coredns:v1.14.3@sha256:884b72dd6d2f7d367902af420605e0288dffedb0516ce29330423ae3f8f5c6fa
  71 │           imagePullPolicy: IfNotPresent
  72 │           livenessProbe:
  73 │             failureThreshold: 5
  74 │             httpGet:
  75 └               path: /health
  ..   
────────────────────────────────────────



📣 Notices:
  - Version 0.74.0 of Trivy is now available, current version is 0.73.0

To suppress version checks, run Trivy scans with the --skip-version-check flag

(Truncated to last 6666 characters out of 253609)

✅ Linters with no issues

actionlint, betterleaks, checkov, git_diff, grype, jsonlint, osv-scanner, prettier, prettier, revive, secretlint, shellcheck, shfmt, syft, trivy-sbom, trufflehog, v8r, v8r, yamllint, zizmor

Notices

⚠️ Your configuration references items that have been removed from MegaLinter and are ignored: REPOSITORY_GITLEAKS. See Removed linters to find their replacements.

See detailed reports in MegaLinter artifacts

MegaLinter is provided by OX Security
Show us your support by starring ⭐ the repository

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Verified in CI, not just locally

A green 🧹 Lint - mega-linter would not have proved this works: REPOSITORY_TRIVY is in DISABLE_ERRORS_LINTERS, so a mistyped --config-data path would still have produced a passing check. Read the job log instead.

CI ran the argument — from the mega-linter log at 14:27:17Z:

- Command: [trivy fs --scanners vuln,misconfig --exit-code 1 --ignorefile .trivyignore.yaml
  --skip-dirs tests --config-data .trivy/data --skip-dirs **/.agents
  --skip-dirs **/megalinter-reports .]

CI reproduces the number: KSV-0125 appears zero times in the whole log, and the scan reports 66 misconfigurations across 16 distinct targets — matching the local measurement exactly. (The raw log sums to 132/32 because every target block is emitted twice; the distinct-target count is 16.)

That is the same 93 → 66 across 29 → 16 measured with scripts/megalinter-scan-counts.sh, now confirmed on CI's own trivy (0.73.0) rather than the local 0.74.0.

Also checked

  • 🔐 Validate EKS Authorization passed without re-approval, as predicted: the rendered-surface fingerprint only moves for HelmRelease and pkg.crossplane.io/* resources (isControllerRBACEmitter), and this change touches a Job's image field.
  • Both overlays ksail workload validate → 582 files, exit 0.
  • ⚠️ Analyze (actions) is red for a reason unrelated to this PR: GitHub's managed CodeQL run (event: dynamic, path: dynamic/github-code-scanning/codeql) failed in Initialize CodeQL with Unable to download and extract CodeQL CLI: API rate limit exceeded — a runner-side transient, no repository workflow file to fix.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

@devantler I will review the changes in #3216.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 68ad175f-3819-43ef-a4b7-cc3589334d68

📥 Commits

Reviewing files that changed from the base of the PR and between 5273766 and e3734f6.

📒 Files selected for processing (4)
  • .mega-linter.yml
  • .trivy/data/trusted-registries.yaml
  • k8s/bases/infrastructure/vault-config/job.yaml
  • scripts/megalinter-scan-counts.sh

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{yaml,yml}: Never run a cluster
Put a change in the layer that matches its scope

Files:

  • k8s/bases/infrastructure/vault-config/job.yaml
🧠 Learnings (7)
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-07-02T06:32:09.574Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2377
File: k8s/bases/infrastructure/vault-config/job.yaml:785-793
Timestamp: 2026-07-02T06:32:09.574Z
Learning: When reviewing OpenBao/Vault `vault-config` Kubernetes YAMLs, treat the infra readonly KV v2 policy pattern `secret/data/infrastructure/<area>/*` (area-wildcard) as an intentional design. Do NOT suggest narrowing these wildcard paths to specific keys as a first response.

Instead, verify the intended blast-radius scoping: each isolation unit `<area>` must have its own `infra-<area>-readonly` Vault policy, and that policy must be bound only to that area's dedicated Kubernetes auth role/ServiceAccount (e.g., `github-config`, `unifi`, `aws`). This should ensure the wildcard’s scope is controlled by the auth role binding rather than by narrowing KV paths.

Also confirm that adding new sibling secrets later under the same `<area>` path should be readable by the existing role without requiring policy edits (i.e., the wildcard path covers the new keys).

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-08-08T15:10:00.349Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 3017
File: k8s/bases/infrastructure/coroot/components/crossplane-sync-exporter/deployment.yaml:13-21
Timestamp: 2026-08-08T15:10:00.349Z
Learning: In the devantler-tech/platform repository, Checkov CI scans source manifests with `--skip-framework kustomize` rather than rendered Kustomize overlays. To suppress a Checkov finding on a base manifest, place the appropriate `checkov.io/skip*` annotation directly in that base YAML file; an overlay patch will not suppress findings reported for the source file.

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-08-08T15:10:00.350Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 3017
File: k8s/bases/infrastructure/coroot/components/crossplane-sync-exporter/deployment.yaml:13-21
Timestamp: 2026-08-08T15:10:00.350Z
Learning: For Kubernetes manifests under k8s/bases/, keep workload-related Checkov exception annotations (checkov.io/skip*) in the base manifest when the checked condition is defined there and CI scans that source manifest directly. Do not move these annotations to overlays solely because the base is immutable; keeping them with the workload ensures the disposition applies consistently to every consumer of the base.

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-08-08T21:23:32.529Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 3025
File: k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml:97-133
Timestamp: 2026-08-08T21:23:32.529Z
Learning: In the devantler-tech/platform repository, modify Kubernetes manifests directly under k8s/bases/ when a configuration change should apply to all Kustomize overlays. Use provider- or cluster-specific overlay patches only for changes that are intentionally limited to those overlays.

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-08-11T12:41:28.242Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 3082
File: k8s/bases/infrastructure/controllers/coroot/cron-job-cnpg-degraded-alert.yaml:113-120
Timestamp: 2026-08-11T12:41:28.242Z
Learning: When changing behavior in Kubernetes manifests or related documentation, review comments and documentation in YAML/YML and Markdown files for statements describing the previous behavior. Update every stale statement in the same change so the repository’s explanatory text remains consistent with the implementation.

Applied to files:

  • k8s/bases/infrastructure/vault-config/job.yaml
📚 Learning: 2026-08-10T13:01:12.782Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 3057
File: .github/workflows/ci.yaml:622-659
Timestamp: 2026-08-10T13:01:12.782Z
Learning: Repository shell tests and scripts must remain compatible with macOS Bash 3.2. Do not use Bash 4+ features such as `mapfile`; use portable constructs, such as a `while IFS= read -r` loop, instead.

Applied to files:

  • scripts/megalinter-scan-counts.sh
🔇 Additional comments (6)
.trivy/data/trusted-registries.yaml (2)

17-21: 🔒 Security & Privacy

Verify the compensating control for suffix matching.

endswith(registry, trusted) makes evil-ghcr.io match ghcr.io. This list is not an exact host allowlist. The file states that signature verification in #2856 covers this, but that enforcement is not shown in this cohort. Verify that a mandatory signature or provenance policy covers every image. Otherwise, add exact-host validation outside KSV-0125 or revise the security guarantee.


25-34: LGTM!

k8s/bases/infrastructure/vault-config/job.yaml (1)

434-434: LGTM!

scripts/megalinter-scan-counts.sh (1)

23-45: LGTM!

Also applies to: 282-282

.mega-linter.yml (2)

140-155: LGTM!


100-100: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep the Trivy documentation consistent. The file records the current scan as 66 misconfigurations across 16 targets, while a later note still cites the older 108-check, 27-target result. Update the older values or mark them as historical. No additional change is needed for the test-only probe; production Trivy invocations should continue using --config-data .trivy/data.

Source: Learnings


📝 Walkthrough

Walkthrough

The change adds KSV-0125 trusted-registry configuration for four registries. Trivy scans now load data from .trivy/data. Scan documentation records root-path requirements and updated finding counts. The Vault store-keys image now uses the fully qualified docker.io/alpine/k8s reference with the same version and digest.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: configuring trusted registries for Trivy KSV-0125.
Description check ✅ Passed The description directly explains the trusted-registry configuration, image qualification, scan measurement, and resulting Trivy findings.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Requesting Cursor Bugbot at this head. CodeRabbit refused (review limit, 41-minute window) and Codex refused (account usage limit for code reviews), both at b661bf9a.

@devantler

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor

cursor Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_0adf3280-9705-4540-94aa-01cc5c8335c0)

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Review-lane state at b661bf9acaa74873bc8e45a29d6d587044416d90 — all three refused

Requested in the mandated priority order, one at a time, each with direct per-PR evidence at this head:

Lane Outcome Evidence
CodeRabbit refused "Review limit reached — next review available in 41 minutes"; head status Review rate limited
Codex refused "You have reached your Codex usage limits for code reviews"
Cursor Bugbot never ran check-run conclusion: neutral + output.title: Error, with "Bugbot couldn't run - usage limit reached"

Bugbot's neutral/Error pair is the did-not-run shape, not a findings result — no inline comments and no review object accompany it. Only a team admin can lift the Cursor and Codex ceilings.

Not securing a review at this head yet, deliberately. This PR carries a second blocker that requires a new commit to clear: GitHub's managed CodeQL run failed in Initialize CodeQL with a runner-side API rate limit exceeded, and it cannot be re-run — POST .../rerun-failed-jobs returns 403 This workflow run cannot be retried, which is expected for an event: dynamic run with no workflow file in the repository. The Require code scanning results ruleset requires CodeQL results, so that has to resolve before merge. Any push to fix it would stale a review secured now, so the review is sequenced after it rather than spent twice.

CodeRabbit's window reopens at roughly 15:13Z; it is the free lane and therefore the one to spend first.

… path-scoped ignores

The reproduction script exists to produce numbers comparable to CI's, and every
other deliberate deviation from the CI command is documented in its header. The
scan root was not, and getting it wrong inflates the count silently.

Measured on this tree with trivy v0.74.0, subcommand and flags held identical
and the scan root the only variable: a root-scoped run reports 66 findings
across 16 targets, a k8s/-scoped run reports 133 across 62. Every check ID
appearing only in the narrowed arm is one .trivyignore.yaml already
dispositions, because those globs are written repository-root-relative and stop
matching once the root moves.

The failure direction is what makes it worth a warning: it reads as more
backlog rather than as a broken measurement.
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

@devantler I will review the changes in #3216.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Resolution record — CodeRabbit ancillary "Merge Risk" note at e3734f62

Its review is finding-free at this head ("No actionable comments were generated in the recent
review", reviewed range ending e3734f62bca203df5168503ebbf711f5d1cfd556), and the only collapsed
section is 🔇 Additional comments (6), which is the non-actionable class. The ancillary Merge Risk
note (🔵 Low) raises two concrete points; both are refuted with reasoning, no file change.

1. "Suffix-based matching could accept a lookalike registry unless signature or provenance
enforcement covers every image."
Correct, and already stated in the change itself rather than
discovered by review. .trivy/data/trusted-registries.yaml carries it as a warning in its own right:

⚠️ MATCHING IS SUFFIX-BASED, NOT EXACT. The check tests endswith(registry, trusted), so an entry
ghcr.io also trusts a registry named evil-ghcr.io. That is upstream behaviour this file cannot
tighten; it is recorded so the guarantee is not overstated.

The PR claims only that the control "catches an unexpected registry, it does not defeat a
deliberately look-alike one", and names digest pinning plus the signature verification tracked in
#2856 as what covers that. So the risk is real, bounded, disclosed at the point of use, and its
covering control is tracked — not an overstated guarantee. Nothing to change.

2. "The stale measurement text should be resolved or explicitly accepted before merge." Checked
rather than accepted, and it is not stale. The counts form one consistent chain, with the historical
transitions marked as history and the current figure stated as current:

Location Text Status
.mega-linter.yml:100 trivy 66 in the local v0.74.0 reproduction current
.mega-linter.yml:124 went 109 → 93 (KubeVirt/CDI RBAC breadth) historical
.mega-linter.yml:140 went 93 → 66 across 29 → 16 targets historical
scripts/megalinter-scan-counts.sh:35 66/16 at root, 133/62 at k8s/ current

The current figure was independently re-measured on this head with trivy v0.74.0 using the CI
invocation from the repository root: 66 findings across 16 targets, matching the documented value
exactly. No text asserts a superseded current count.

Readiness

Programmatically tested. All required checks green at e3734f62, including Analyze (actions)
and CodeQL — the failure that blocked the previous head was a runner-side rate limit in
Initialize CodeQL on a GitHub-managed run that returns 403 cannot be retried, so it needed a new
commit rather than a re-run. 🧹 Lint - mega-linter passes on the changed script; bash -n parses it.

Reviewed. CodeRabbit green at this exact head (above).

Tried and evaluated as a user. The registry list was ablation-verified when it landed: removing
the single quay.io entry returns exactly 11 findings, all 11 quay.io-hosted. This head's added
documentation was verified by running the thing it documents — both scan roots, same subcommand and
flags, root as the only variable: . → 66 findings/16 targets, k8s/ → 133/62. Every check ID
appearing only in the narrowed arm (KSV-0022, KSV-0037, KSV-0053, KSV-0109, KSV-0114, KSV-0117) is
one .trivyignore.yaml already dispositions, and KSV-0037 alone accounts for 47 of the 67 extra —
which is the mechanism the warning describes, observed rather than reasoned about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant