Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
99 lines
4.2 KiB
YAML
99 lines
4.2 KiB
YAML
# =============================================================================
|
|
# L2 BEHAVIORAL SCAFFOLD — Default-deny east-west (R-NET-01)
|
|
# Catalog: docs/14-testing-and-conformance.md "Default-deny (R-NET-01)"
|
|
# Spec: docs/03-networking-isolation-and-egress.md "Default-deny baseline"
|
|
#
|
|
# EXEMPLAR: this file is the reference for the tagging convention and step
|
|
# style. Other scaffolds follow the same shape (see tests/README.md).
|
|
#
|
|
# GIVEN a fresh workload in a namespace with no allow rules,
|
|
# WHEN it attempts any in-cluster connection except DNS,
|
|
# THEN the connection FAILS (fail-closed); DNS still succeeds.
|
|
#
|
|
# This asserts observable BEHAVIOR (a probe cannot connect), not the mere
|
|
# existence of a NetworkPolicy object (R-TEST-01). Safety-relevant: the
|
|
# fail-closed direction is also exercised under fault-injection at L3
|
|
# (kill-switch / drift), but the baseline deny is a behavioral must-pass.
|
|
#
|
|
# STATUS: scaffold — cannot run until Phase 2 delivers the default-deny
|
|
# baseline (T-2.2). Chainsaw auto-creates/cleans the namespace (hermetic).
|
|
# TODOs mark fixtures that land as later phases deliver.
|
|
# =============================================================================
|
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
|
kind: Test
|
|
metadata:
|
|
name: default-deny
|
|
labels:
|
|
# --- requirement tags (authoritative; one label per verified R-* ID) ---
|
|
conformance.home.k3s/R-NET-01: "true"
|
|
annotations:
|
|
conformance.home.k3s/requirements: "R-NET-01"
|
|
conformance.home.k3s/layer: "L2"
|
|
conformance.home.k3s/safety-critical: "false"
|
|
conformance.home.k3s/intent: >-
|
|
Given a bare workload with no allow rules, only DNS egress succeeds;
|
|
every other in-cluster connection is denied.
|
|
spec:
|
|
steps:
|
|
# -- GIVEN: a fresh, unprivileged probe workload with zero allow rules. The
|
|
# per-test namespace inherits the platform default-deny baseline (T-2.2).
|
|
- name: given-bare-probe-workload
|
|
try:
|
|
- apply:
|
|
# TODO(T-2.2): once the namespaced default-deny CiliumNetworkPolicy
|
|
# baseline exists, assert it is present AND that the probe below is
|
|
# actually blocked (existence != enforcement, R-TEST-01).
|
|
resource:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: probe
|
|
labels: { app: conformance-probe }
|
|
spec:
|
|
restartPolicy: Never
|
|
containers:
|
|
- name: probe
|
|
image: ghcr.io/kyverno/kyvernopre:latest # TODO: pin a curl/nc probe image
|
|
command: ["sleep", "3600"]
|
|
- assert:
|
|
resource:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata: { name: probe }
|
|
status: { phase: Running }
|
|
|
|
# -- THEN(DNS allowed): DNS egress MUST succeed even under default-deny.
|
|
- name: then-dns-succeeds
|
|
try:
|
|
- script:
|
|
# TODO(T-2.2): resolve an in-cluster name via kube-dns; expect rc=0.
|
|
content: |
|
|
set -euo pipefail
|
|
kubectl -n "$NAMESPACE" exec probe -- \
|
|
sh -c 'nslookup kubernetes.default.svc.cluster.local' && echo DNS_OK
|
|
check:
|
|
# bounded, deterministic: no sleeps; chainsaw retries within timeout.
|
|
($stdout =~ 'DNS_OK'): true
|
|
|
|
# -- THEN(everything else denied): a non-DNS in-cluster connection MUST fail.
|
|
- name: then-nondns-denied
|
|
try:
|
|
- script:
|
|
# TODO(T-2.2 / T-2.6): target an in-cluster service (e.g. Plex/Gateway)
|
|
# on a real port; expect the connection to FAIL closed (non-zero / timeout).
|
|
content: |
|
|
set -euo pipefail
|
|
if kubectl -n "$NAMESPACE" exec probe -- \
|
|
sh -c 'nc -z -w 3 <in-cluster-service> 80'; then
|
|
echo "LEAK: connection succeeded under default-deny" >&2
|
|
exit 1
|
|
fi
|
|
echo DENIED_OK
|
|
check:
|
|
($stdout =~ 'DENIED_OK'): true
|
|
# -- finally: chainsaw deletes the namespace + probe automatically; this block
|
|
# is the explicit hook for any out-of-namespace fixtures (none here).
|
|
finally:
|
|
- script:
|
|
content: 'echo "cleanup handled by chainsaw namespace teardown"'
|