Add supply-chain v1 artifacts (build/sign, verification, k8s, docs)#13
Add supply-chain v1 artifacts (build/sign, verification, k8s, docs)#13codevantaceo merged 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds “supply-chain v1” artifacts to the repo, including CI helper scripts, a verification gate, dependency/license/vuln evaluation, monitoring helpers, policy/manifests, workflow wiring, and quickstart documentation.
Changes:
- Introduces CI helper scripts for build/SBOM/sign and verification/dependency gating under
scripts/ci/. - Adds monitoring helpers (
AuditLogger,AnomalyDetector) plus corresponding tests. - Adds policy/manifests/configs/docs and a GitHub Actions workflow to run the supply-chain pipeline.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_supplychain_v1.py | Adds unit tests covering dry-run command emission, SBOM checks, dependency gate behavior, and monitoring helpers. |
| scripts/ci/build_sign_show.py | Implements build → SBOM → sign helper functions and CLI wrapper. |
| scripts/ci/verify_gate.py | Implements signature/attestation/SBOM verification gate + CLI. |
| scripts/ci/dependericy_check.py | Implements CycloneDX SBOM evaluation for vulnerabilities/licenses + CLI report. |
| scripts/monitoring/audit_logger.py | Adds JSONL audit logging helper. |
| scripts/monitoring/anomaly_detector.py | Adds anomaly scanning for event feeds + CLI. |
| scripts/init.py | Makes scripts importable as a package. |
| scripts/ci/init.py | Marks CI helpers as a package module. |
| scripts/monitoring/init.py | Marks monitoring helpers as a package module. |
| policy/rego/supplychain.rego | Adds baseline OPA/Rego policy for supply-chain checks. |
| k8s/supplychain/deployment.yaml | Adds K8s namespace/service/deployment/configmap scaffolding for supply-chain service. |
| .github/workflows/_build_sign_sbom.yml | Adds CI workflow to build image, generate SBOM, and cosign sign/verify. |
| Dockerfile | Adds container packaging for running the IaOps engine. |
| docs/supplychain.md | Adds supply-chain quickstart/usage documentation. |
| configs/supplychain.env.example | Adds example environment settings for supply-chain tasks. |
| configs/supplychain.defaults.yaml | Adds default supply-chain configuration values. |
| README.md | Documents new supply-chain v1 artifacts and how to find them. |
| PROJECT_TREE.txt | Updates repository tree snapshot to include new artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| from pathlib import Path | ||
| from typing import Iterable | ||
|
|
There was a problem hiding this comment.
This file imports Iterable from typing, but the repo’s ruff config enables UP rules and existing modules import Iterable from collections.abc. Switch to collections.abc.Iterable to match the codebase convention and avoid ruff violations.
| - Verification Gate: `scripts/ci/verify_gate.py` checks signatures, attestations, and SBOM presence. | ||
| - Dependency Management: `scripts/ci/dependericy_check.py` evaluates CycloneDX SBOM data for vulnerabilities and license policy. | ||
| - Audit Logging: `scripts/monitoring/audit_logger.py` writes JSONL audit events. |
There was a problem hiding this comment.
The path scripts/ci/dependericy_check.py appears to contain a typo ("dependericy" vs "dependency"). Consider renaming the module and updating references so the docs don’t bake in the misspelling.
| - CI helpers live under `scripts/ci/`: | ||
| - `build_sign_show.py` builds the image, generates a CycloneDX SBOM with Syft, and signs via Cosign. | ||
| - `verify_gate.py` verifies signatures, attestations, and SBOM presence. | ||
| - `dependericy_check.py` evaluates SBOM data for vulnerabilities and license policy. |
There was a problem hiding this comment.
The filename dependericy_check.py looks like a typo ("dependericy" vs "dependency"). If renamed, update the README references at the same time to avoid locking the typo into user docs.
| - `dependericy_check.py` evaluates SBOM data for vulnerabilities and license policy. | |
| - `dependency_check.py` evaluates SBOM data for vulnerabilities and license policy. |
| parser.add_argument("--identity-token", help="OIDC identity token for keyless signing.") | ||
| parser.add_argument("--annotation", action="append", default=[], help="Annotations for the signature key=value.") | ||
| parser.add_argument("--no-keyless", action="store_true", help="Disable keyless signing even when key is absent.") | ||
| parser.add_argument("--dry-run", action="store_true", help="Print commands without executing them.") |
There was a problem hiding this comment.
The --dry-run option is described as "Print commands without executing them", but dry_run=True only returns a CommandResult and does not print anything. Either print the command(s) when dry-run is enabled, or adjust the help text to match the actual behavior.
| parser.add_argument("--dry-run", action="store_true", help="Print commands without executing them.") | |
| parser.add_argument("--dry-run", action="store_true", help="Run the pipeline without executing external commands.") |
| def is_blocking(self) -> bool: | ||
| return (self.severity or "").lower() in {"critical", "high"} | ||
|
|
There was a problem hiding this comment.
License policy violations are recorded as severity "policy" (and a "LICENSE_POLICY" marker), but neither DependencyFinding.is_blocking nor the fail_levels gate treats "policy" as a failure. As a result, a disallowed license will not fail the gate despite the CLI/docs implying it should. Decide on the intended behavior and either treat policy findings as blocking (and include them in the failure check), or rename/adjust the messaging to match the current behavior.
| from pathlib import Path | ||
|
|
||
| from scripts.ci.build_sign_show import build_image, generate_sbom, sign_image | ||
| from scripts.ci.dependericy_check import evaluate_dependencies, summarize |
There was a problem hiding this comment.
The module/file name dependericy_check appears to be a misspelling of "dependency". Renaming it to dependency_check.py (and updating imports) would improve discoverability and avoid propagating the typo into user-facing docs/CLI examples.
| from scripts.ci.dependericy_check import evaluate_dependencies, summarize | |
| from scripts.ci.dependency_check import evaluate_dependencies, summarize |
| from pathlib import Path | ||
| from typing import Iterable | ||
|
|
There was a problem hiding this comment.
This file imports Iterable from typing, but the repo enables ruff UP rules and uses collections.abc.Iterable elsewhere. Update the import to match the established convention and avoid ruff violations.
|
|
||
| ENV IAOPS_CONFIG=/app/configs/indestructibleautoops.pipeline.yaml | ||
|
|
||
| ENTRYPOINT ["python", "-m", "indestructibleautoops", "run", "--config", "/app/configs/indestructibleautoops.pipeline.yaml", "--project", "."] |
There was a problem hiding this comment.
ENTRYPOINT ["python", "-m", "indestructibleautoops", ...] will fail because the package has no indestructibleautoops/__main__.py (only main.py). Either add an __main__.py that invokes the Click CLI, or change the entrypoint to the installed console script (or python -m indestructibleautoops.main).
| ENTRYPOINT ["python", "-m", "indestructibleautoops", "run", "--config", "/app/configs/indestructibleautoops.pipeline.yaml", "--project", "."] | |
| ENTRYPOINT ["python", "-m", "indestructibleautoops.main", "run", "--config", "/app/configs/indestructibleautoops.pipeline.yaml", "--project", "."] |
| - name: Sign image | ||
| env: | ||
| COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} | ||
| run: | | ||
| cosign sign --yes --key "${{ secrets.COSIGN_PRIVATE_KEY }}" ghcr.io/${{ github.repository_owner }}/iaops:${{ github.sha }} |
There was a problem hiding this comment.
This step attempts to cosign sign an image tag under ghcr.io/..., but the workflow never pushes (or loads) the image. Unless the image is made available (e.g., push: true with appropriate permissions, or a local/OCI-layout approach), signing will fail.
| import json | ||
| from dataclasses import dataclass | ||
| from pathlib import Path | ||
| from typing import Iterable |
There was a problem hiding this comment.
Import of 'Iterable' is not used.
| from typing import Iterable |
The supply-chain v1 scope required concrete build/sign, verification, k8s, workflow, and documentation deliverables (Cosign/SBOM/OPA, verification gate, deployment manifests, and usage guides).
Build/Sign + Verification
scripts/ci/build_sign_show.py(docker build + Syft SBOM + Cosign sign),scripts/ci/verify_gate.py(signature/attestation/SBOM checks), andscripts/ci/dependericy_check.py(CycloneDX vuln/license gate).K8s + Policy Artifacts
policy/rego/supplychain.rego, k8s deploymentk8s/supplychain/deployment.yaml, and Docker packagingDockerfile.CI Workflow + Configs
_build_sign_sbom.ymlfor build/SBOM/sign/verify, plus defaults/env templates underconfigs/.Monitoring + Docs + Tests
scripts/monitoring/), quickstart docsdocs/supplychain.md, README additions, and coverage intests/test_supplychain_v1.py.Example (build+sign+SBOM):