T-0.5 Kyverno L0 policies + CLI tests + admission scaffolding (R-TEST-01, R-NET-01, R-SEC-01/02, R-IDP-02, R-GITOPS-02)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
bb08d0e048
commit
bb2e9fc931
28 files changed
+1243
-2
No files matched your search
@@ -0,0 +1,58 @@
|
||||
# ServiceDefinition L0 validation (R-GITOPS-02)
|
||||
|
||||
Validates the shape of each `catalog/` **ServiceDefinition** against the canonical
|
||||
schema and invariants in the read-only spec `docs/13-service-catalog.md` (with
|
||||
`auth` from `docs/15`, `egress` from `docs/03`). Runs in CI **without a cluster**.
|
||||
|
||||
## Why kyverno-json (not the resource CLI)
|
||||
|
||||
A ServiceDefinition is **arbitrary YAML** — its own `kind:` field means
|
||||
`container | vm`, not a Kubernetes Kind — so it cannot be validated by
|
||||
`kyverno apply`/`kyverno test` (which expect Kubernetes resources). Per
|
||||
[ADR-0011] the Kyverno-ecosystem tool for arbitrary YAML/JSON is **kyverno-json**.
|
||||
|
||||
## Invariants enforced (`validate-servicedefinition.yaml`)
|
||||
|
||||
- `name` is a DNS-1123 label (→ `<name>.home.keithjackson.dev`).
|
||||
- `kind` ∈ {`container`, `vm`}; container ⇒ `source.image`, vm ⇒ `source.vmTemplate`.
|
||||
- `exposure` ∈ {`internal`, `public`}.
|
||||
- `egress` ∈ {`internet`, `vpn`}.
|
||||
- `auth.mode` ∈ {`oidc`, `forward-auth`, `native`, `none`}.
|
||||
- **`public` exposure ⇒ `auth.mode` ≠ `none`** (no unauthenticated public UI, docs/15).
|
||||
- each `dependencies[]` has `to`, `port` ∈ 1–65535, `protocol` ∈ {`tcp`, `udp`}.
|
||||
- each `storage[].class` ∈ {`longhorn`, `bulk`}.
|
||||
|
||||
## Fixtures
|
||||
|
||||
`payloads/valid-*.yaml` must PASS; `payloads/invalid-*.yaml` must FAIL — one failure
|
||||
reason each (bad egress, public+none auth, missing image, bad dependency).
|
||||
|
||||
## Run (CI entrypoint)
|
||||
|
||||
```bash
|
||||
# Valid payloads: scan must exit 0
|
||||
kyverno-json scan \
|
||||
--policy validate-servicedefinition.yaml \
|
||||
--payload payloads/valid-plex.yaml \
|
||||
--payload payloads/valid-sonarr.yaml
|
||||
|
||||
# Invalid payloads: each scan must exit NON-zero (loop asserts failure)
|
||||
for f in payloads/invalid-*.yaml; do
|
||||
if kyverno-json scan --policy validate-servicedefinition.yaml --payload "$f"; then
|
||||
echo "FAIL: expected $f to be rejected"; exit 1
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
The `scripts/run-l0.sh` wrapper (see `../README.md`) runs both halves and is what CI
|
||||
invokes.
|
||||
|
||||
## Caveat (escalated in the T-0.5 report)
|
||||
|
||||
kyverno-json is **pre-1.0**; its assertion syntax evolves. The **invariants above are
|
||||
the normative content**. The CI agent must pin an exact kyverno-json version and
|
||||
confirm the `check:` expressions parse under it; adjust syntax (never the invariants)
|
||||
if the pinned release differs. The overlapping JSON Schema from WS-GITOPS (T-0.3) is
|
||||
the complementary structural contract.
|
||||
|
||||
[ADR-0011]: ../../../../home-network-k3s/decisions/adr-0011-test-tooling-kyverno-chainsaw.md
|
||||
Reference in new issue
Block a user