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,65 @@
|
||||
# Serves: R-GITOPS-02 (the ServiceDefinition is the onboarding contract; it must be
|
||||
# shape-valid before it can be rendered).
|
||||
# Spec: docs/13-service-catalog.md "Fields (canonical schema)" + "Default posture";
|
||||
# docs/15 (auth); docs/03 (egress).
|
||||
#
|
||||
# ServiceDefinitions are ARBITRARY YAML (their own `kind:` field is container|vm, NOT
|
||||
# a Kubernetes Kind), so they are validated with kyverno-json (per ADR-0011:
|
||||
# "kyverno-json for arbitrary YAML/JSON like ServiceDefinitions"), not the resource
|
||||
# CLI. This policy encodes the docs/13 invariants only; the full JSON Schema +
|
||||
# renderer contract is WS-GITOPS T-0.3 and is complementary, not a substitute.
|
||||
#
|
||||
# NOTE (see servicedefinition/README.md): kyverno-json is pre-1.0. The INVARIANTS
|
||||
# below are the normative content; the CI agent must confirm the assertion syntax
|
||||
# against the pinned kyverno-json release.
|
||||
apiVersion: json.kyverno.io/v1alpha1
|
||||
kind: ValidatingPolicy
|
||||
metadata:
|
||||
name: validate-servicedefinition
|
||||
annotations:
|
||||
homelab.keithjackson.dev/requirements: R-GITOPS-02
|
||||
spec:
|
||||
rules:
|
||||
- name: servicedefinition-shape
|
||||
assert:
|
||||
all:
|
||||
- message: "`name` must be a DNS-1123 label"
|
||||
check:
|
||||
(regex_match('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$', name)): true
|
||||
- message: "`kind` must be 'container' or 'vm'"
|
||||
check:
|
||||
(kind == 'container' || kind == 'vm'): true
|
||||
- message: "`exposure` must be 'internal' or 'public'"
|
||||
check:
|
||||
(exposure == 'internal' || exposure == 'public'): true
|
||||
- message: "`egress` must be 'internet' or 'vpn'"
|
||||
check:
|
||||
(egress == 'internet' || egress == 'vpn'): true
|
||||
- message: "container kind requires `source.image`"
|
||||
check:
|
||||
(kind != 'container' || source.image != null): true
|
||||
- message: "vm kind requires `source.vmTemplate`"
|
||||
check:
|
||||
(kind != 'vm' || source.vmTemplate != null): true
|
||||
- message: "`auth.mode` must be one of oidc|forward-auth|native|none"
|
||||
check:
|
||||
(auth.mode == 'oidc' || auth.mode == 'forward-auth' || auth.mode == 'native' || auth.mode == 'none'): true
|
||||
- message: "public exposure must not use auth.mode 'none' -- no unauthenticated public UI (docs/15, R-IDP-02)"
|
||||
check:
|
||||
(exposure != 'public' || auth.mode != 'none'): true
|
||||
- name: servicedefinition-dependencies
|
||||
assert:
|
||||
all:
|
||||
- message: "each dependency needs `to`, `port` (1-65535) and `protocol` tcp|udp"
|
||||
check:
|
||||
~.dependencies:
|
||||
(to != null): true
|
||||
(port >= `1` && port <= `65535`): true
|
||||
(protocol == 'tcp' || protocol == 'udp'): true
|
||||
- name: servicedefinition-storage
|
||||
assert:
|
||||
all:
|
||||
- message: "each storage entry's `class` must be 'longhorn' or 'bulk'"
|
||||
check:
|
||||
~.storage:
|
||||
(class == 'longhorn' || class == 'bulk'): true
|
||||
Reference in new issue
Block a user