Security
This page summarizes how ClawQL builds, proves, and enforces container images from CI through Kubernetes admission. For every detail, use the repo docs linked below.
Golden image pipeline (end to end)
Canonical write-up: golden-image-pipeline.md — single narrative for operators and security reviewers.
At a glance:
- Repository gates — Workflow
repo-supply-chainin.github/workflows/docker-publish.yml: OSV-Scanner (withosv-scanner.toml), Trivy filesystem (HIGH / CRITICAL,.trivyignore), Syft CycloneDX SBOM artifact. If this job fails, neither the MCP nor website image jobs run. - One BuildKit build per image —
docker buildx buildwrites a local OCI layout (type=oci,tar=false):clawql-mcp(docker/Dockerfile) andclawql-website(website/Dockerfile), multi-arch, with BuildKit provenance and SBOM attestations. No GHCR write yet. - Trivy on that layout — Same bytes that will be pushed are scanned (HIGH / CRITICAL). Failure blocks registry upload for that image.
skopeo copy— Pushes exactly the scanned OCI layout to GHCR (immutablesha-*tags first). No second build — avoids drift between “scanned” and “released” artifacts.- Cosign keyless —
cosign signon the digest using GitHub Actions OIDC (Fulcio / Rekor). - Tag promotion —
docker buildx imagetools createadvanceslatest,nightly, and schedulednightly-YYYYMMDDonly after the above succeed.
Main branch CI (ci.yml) runs a similar supply-chain job (OSV + Trivy fs + repository SBOM) so merges are gated before docker-publish runs on schedule or workflow_dispatch.
How we enforce it (build vs cluster)
| Where | What happens |
|---|---|
| GitHub Actions | Failed OSV/Trivy/SBOM steps or failed image scan → no push, no sign, no tag promotion for that run. |
| GHCR + Sigstore | Signatures bind to the digest that passed the pipeline; cosign verify (see docker/README.md) proves identity out-of-band. |
| Kubernetes | The Helm chart defaults kyverno.imageSignaturePolicy.enabled: true, rendering a ClusterPolicy with Kyverno verifyImages for ghcr.io/danielsmithdevelopment/clawql-mcp* and clawql-website* (Cosign keyless issuer/subject regexes). Install Kyverno before helm upgrade, or opt out with --set kyverno.imageSignaturePolicy.enabled=false until your cluster has it. Policy fields, digest-only options, and forks: image-signature-enforcement.md. |
| Docker Desktop | make local-k8s-up installs Kyverno, uses signed GHCR images for MCP/UI, scopes policy to the release namespace, and rejects unsigned local image env overrides — see Kubernetes and scripts/kubernetes/local-k8s-docker-desktop.sh. |
Important limits: the Kyverno rule matches ClawQL’s two GHCR image patterns only; other containers in the same namespace (databases, Onyx stack, etc.) are not covered by that policy. CI signing does not stop arbitrary kubectl if someone bypasses admission—Kyverno (or equivalent) is what ties deployed ClawQL images to the signed digests from this pipeline.
npm and other artifacts
Container images are not npm packages. npm publish hardening (pack → scan → publish, OIDC provenance): npm-supply-chain.md (#156).
Security references (repo)
- Security docs index
- Golden image pipeline (full E2E + enforcement)
- Defense in depth guide
- Deliverables matrix (shipped / partial / planned)
- Image signature enforcement (Kyverno details)
