feat(security): validate shell and Kubernetes sources #13

Merged
gitchegumi merged 4 commits from feat/kubernetes-validation into main 2026-09-04 20:07:48 -05:00
Member

Adds ShellCheck to source scans and explicit Helm/Kustomize rendering, strict Kubernetes schema validation, and Trivy scanning of rendered manifests through .pipeline/validation.json. Tool downloads are checksum-pinned, paths are constrained to the checkout, and Helm does not fetch dependencies.

Kubeconform fails on missing schemas, including misspelled built-in kinds and unsupported custom resources. Skipping is disabled; success requires at least one valid resource and zero invalid, errored, or skipped resources. Controller-specific schema support remains a future capability.

Incorporates current main, resolves the test conflict while retaining PR #12 self-scan tests and policy, and updates the exact existing Semgrep mitigation for the relocated rule-download line without changing its controls or expiry.

Validation: 38 unit/contract tests; YAML/Bash syntax and 16 mocked scaffold cases; five production-command cases using checksum-verified Kubeconform 0.7.0 (valid resource, misspelled built-in, invalid built-in, unknown custom resource, and empty input). These real-tool cases also run in Library checks. Both Library checks and Repository security are required verification for this updated branch.

Advances #4.

Adds ShellCheck to source scans and explicit Helm/Kustomize rendering, strict Kubernetes schema validation, and Trivy scanning of rendered manifests through `.pipeline/validation.json`. Tool downloads are checksum-pinned, paths are constrained to the checkout, and Helm does not fetch dependencies. Kubeconform fails on missing schemas, including misspelled built-in kinds and unsupported custom resources. Skipping is disabled; success requires at least one valid resource and zero invalid, errored, or skipped resources. Controller-specific schema support remains a future capability. Incorporates current main, resolves the test conflict while retaining PR #12 self-scan tests and policy, and updates the exact existing Semgrep mitigation for the relocated rule-download line without changing its controls or expiry. Validation: 38 unit/contract tests; YAML/Bash syntax and 16 mocked scaffold cases; five production-command cases using checksum-verified Kubeconform 0.7.0 (valid resource, misspelled built-in, invalid built-in, unknown custom resource, and empty input). These real-tool cases also run in Library checks. Both Library checks and Repository security are required verification for this updated branch. Advances #4.
feat(security): validate shell and Kubernetes sources
All checks were successful
Library checks / tests (pull_request) Successful in 1m33s
679e1e2197
Add checksum-pinned ShellCheck, Helm, Kustomize, and Kubeconform tooling. Render explicitly configured local manifests before schema and IaC validation so reusable scans cover deployment sources without downloading chart dependencies.
gitchegumi approved these changes 2026-09-04 16:58:45 -05:00
Dismissed
portegumi requested changes 2026-09-04 17:05:25 -05:00
Dismissed
portegumi left a comment

Blocking:

  1. pipeline/security.py:247-249 combines Kubeconform -strict with -ignore-missing-schemas, which silently accepts every unknown GVK, not only CRDs. I reproduced this with the exact checksum-pinned Kubeconform 0.7.0 binary: an apps/v1 resource whose kind was misspelled as Deploymnt produced valid: 0, invalid: 0, errors: 0, skipped: 1 and exited 0. This defeats the stated strict built-in validation. Make CRD skipping explicit (for example, declared custom-kind/schema handling), reject every unexpected skipped resource, and add a production-command regression using a misspelled built-in kind.

  2. The branch is three commits behind current main, Forgejo reports it non-mergeable, and a three-way merge simulation produces a content conflict in tests/test_security.py. Incorporate current main, preserve PR #12's self-scan mitigation coverage while resolving the conflict, and rerun both the library and repository-security checks. The current green result contains only Library checks because this branch predates the repository self-scan.

Validation at this head: 35 Python 3.12 tests passed; YAML/Bash and all 16 mocked scaffold cases passed; git diff --check passed; the Kubeconform reproduction used a binary whose SHA-256 matched tools.lock.json.

Blocking: 1. `pipeline/security.py:247-249` combines Kubeconform `-strict` with `-ignore-missing-schemas`, which silently accepts every unknown GVK, not only CRDs. I reproduced this with the exact checksum-pinned Kubeconform 0.7.0 binary: an `apps/v1` resource whose kind was misspelled as `Deploymnt` produced `valid: 0, invalid: 0, errors: 0, skipped: 1` and exited 0. This defeats the stated strict built-in validation. Make CRD skipping explicit (for example, declared custom-kind/schema handling), reject every unexpected skipped resource, and add a production-command regression using a misspelled built-in kind. 2. The branch is three commits behind current `main`, Forgejo reports it non-mergeable, and a three-way merge simulation produces a content conflict in `tests/test_security.py`. Incorporate current `main`, preserve PR #12's self-scan mitigation coverage while resolving the conflict, and rerun both the library and repository-security checks. The current green result contains only `Library checks` because this branch predates the repository self-scan. Validation at this head: 35 Python 3.12 tests passed; YAML/Bash and all 16 mocked scaffold cases passed; `git diff --check` passed; the Kubeconform reproduction used a binary whose SHA-256 matched `tools.lock.json`.
fix(security): reject unknown Kubernetes resource schemas
Some checks failed
Repository security / security (pull_request) Has been cancelled
Library checks / tests (pull_request) Has been cancelled
Repository security / security-1 (pull_request) Has been cancelled
059b2dc526
Incorporate main and preserve repository self-scan coverage. Reject missing schemas and incomplete validation reports, and exercise the production command with positive and negative fixtures in CI.
fix(security): retain mitigation for relocated rule download
All checks were successful
Repository security / security-1 (pull_request) Successful in 1m14s
Repository security / security (pull_request) Successful in 0s
Library checks / tests (pull_request) Successful in 1m35s
df5869af02
gitchegumi approved these changes 2026-09-04 17:41:50 -05:00
portegumi requested changes 2026-09-04 17:42:28 -05:00
Dismissed
portegumi left a comment

Re-review: the two previous blockers are resolved. The branch now contains current main, is mergeable, preserves PR #12 coverage, removes -ignore-missing-schemas, and exercises the exact Kubeconform command against the reported negative cases. One blocker remains:

  • validation_config() accepts {"manifests": [], "render": []}. In scan(), that leaves manifests empty, so the if manifests: guard skips validate_kubernetes() entirely and the configured Kubernetes-validation stage succeeds without producing or checking a Kubeconform report. This contradicts the documented contract that success requires at least one valid resource. The new empty production-command fixture does not cover this path because it calls validate_kubernetes() directly with an empty file rather than loading an empty validation plan. Require at least one manifest pattern or render entry at configuration validation, and add a regression covering an empty .pipeline/validation.json plan through the configuration/scan path.

Verification at this head: 38 Python 3.12 tests pass; YAML/Bash and all 16 mocked scaffold cases pass; all five exact-binary Kubeconform production cases pass; git diff --check is clean; both hosted workflows are green; the hosted security decision reports passed: true, zero blocking findings, five exact mitigations, and zero scanner errors.

Re-review: the two previous blockers are resolved. The branch now contains current `main`, is mergeable, preserves PR #12 coverage, removes `-ignore-missing-schemas`, and exercises the exact Kubeconform command against the reported negative cases. One blocker remains: - `validation_config()` accepts `{"manifests": [], "render": []}`. In `scan()`, that leaves `manifests` empty, so the `if manifests:` guard skips `validate_kubernetes()` entirely and the configured Kubernetes-validation stage succeeds without producing or checking a Kubeconform report. This contradicts the documented contract that success requires at least one valid resource. The new `empty` production-command fixture does not cover this path because it calls `validate_kubernetes()` directly with an empty file rather than loading an empty validation plan. Require at least one manifest pattern or render entry at configuration validation, and add a regression covering an empty `.pipeline/validation.json` plan through the configuration/scan path. Verification at this head: 38 Python 3.12 tests pass; YAML/Bash and all 16 mocked scaffold cases pass; all five exact-binary Kubeconform production cases pass; `git diff --check` is clean; both hosted workflows are green; the hosted security decision reports `passed: true`, zero blocking findings, five exact mitigations, and zero scanner errors.
fix(security): reject empty Kubernetes validation plans
All checks were successful
Repository security / security-1 (pull_request) Successful in 1m16s
Repository security / security (pull_request) Successful in 0s
Library checks / tests (pull_request) Successful in 2m11s
bce08540a9
Require a manifest pattern or render entry before scanning. Cover empty-plan configuration rejection and the full scan decision in CI, while retaining the exact mitigation for the shifted rule download.
portegumi approved these changes 2026-09-04 20:06:53 -05:00
portegumi left a comment

Re-review complete. The empty-plan bypass is fixed at configuration validation, with both focused unit coverage and a full scan-path regression proving that an empty .pipeline/validation.json plan produces a failed decision and no Kubeconform report. The earlier unknown-GVK and branch-synchronization blockers remain resolved.

Verified at this head: the branch contains current main and is mergeable; all three Forgejo checks are green; 39 Python 3.12 unit/contract tests pass locally; YAML/Bash and all 16 mocked scaffold cases pass; all five exact-binary Kubeconform production cases pass; git diff --check is clean. The fresh hosted security artifact reports passed: true, zero blocking findings, five exact mitigations, and zero scanner errors. No blocking findings remain.

Re-review complete. The empty-plan bypass is fixed at configuration validation, with both focused unit coverage and a full scan-path regression proving that an empty `.pipeline/validation.json` plan produces a failed decision and no Kubeconform report. The earlier unknown-GVK and branch-synchronization blockers remain resolved. Verified at this head: the branch contains current `main` and is mergeable; all three Forgejo checks are green; 39 Python 3.12 unit/contract tests pass locally; YAML/Bash and all 16 mocked scaffold cases pass; all five exact-binary Kubeconform production cases pass; `git diff --check` is clean. The fresh hosted security artifact reports `passed: true`, zero blocking findings, five exact mitigations, and zero scanner errors. No blocking findings remain.
gitchegumi deleted branch feat/kubernetes-validation 2026-09-04 20:07:48 -05:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Homelab/workflows!13
No description provided.