# ============================================================================= # L0 STATIC — certificate lifecycle needs no manual step (R-TLS-02) [EXECUTABLE] # Catalog: docs/14 L0 row ("Pre-apply, in CI") — runs WITHOUT a cluster. # Spec: docs/00 R-TLS-02 ("Certificates MUST be automatically issued, renewed, and # revoked without manual steps"); mechanism in docs/08 + ADR-0006. # # R-TLS-02 is one adverbial clause plus three runtime verbs. This test asserts the # clause — "without manual steps" — which in a GitOps platform is a property of the # REPOSITORY: a human step in the certificate path leaves evidence in git (committed # cert material, a Gateway serving a Secret nothing declares, an issuer with no # automated solver, a credential never delivered, auto-approval switched off, or CRs # nothing reconciles). The three verbs are observed by the companion L2 test. # # ENVIRONMENT-AGNOSTIC (R-ENV-02): the issuer a Certificate names is `${ACME_CLUSTER_ISSUER}`, # so the check resolves it against the BASE cluster-vars default AND every overlay's value and # requires each resolved issuer to exist. dev's issuer and prod's issuer are both verified from # one authored assertion, with no hostname, address or environment name written down. # # GIVEN the repository as git tracks it, # WHEN every serving-TLS reference, Certificate, Issuer and the cert-manager release # is inspected offline, # THEN every Gateway listener that terminates TLS serves a Secret a tracked Certificate # produces; no certificate material is committed anywhere; every Certificate's # issuer resolves — in EVERY environment — to a tracked ACME issuer with an # automated dns01/http01 solver whose credential is SOPS-delivered from git; # cert-manager's automatic request approval is not disabled; and every one of # those objects is rendered by a Flux Kustomization, so nothing in the chain # depends on a human running kubectl. # # STATUS: EXECUTABLE. `check.sh` is a pure offline assertion script (git + PyYAML, no # cluster, no network); conformance/run.sh --layer l0 and ci/l0.sh run it directly, and # this Chainsaw Test wraps the SAME script. # # KNOWN, DELIBERATE GAPS (named in check.sh's header too — this test claims NONE of them): # * ISSUED / RENEWED as runtime events: L2 (l2-behavioral/cert-lifecycle-automated). # * REVOKED: not proven at any layer today. cert-manager performs no ACME revocation, # and the spec's own reading (docs/08: "removing/rotating a certificate is a # declarative change") needs `enableCertificateOwnerRef`, which the tracked # cert-manager HelmRelease does not set — so a removed Certificate leaves its # serving Secret behind. The L2 test asserts the withdrawal behaviour and is # EXPECTED TO FAIL until that knob is set; escalated, not softened (R-TEST-06). # * That the live cluster is serving the tracked Certificate (cluster state). # ============================================================================= apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: name: tls-lifecycle-automated labels: conformance.home.k3s/R-TLS-02: "true" annotations: conformance.home.k3s/requirements: "R-TLS-02" conformance.home.k3s/layer: "L0" # WHOLE-REPO SCOPE. Universally quantified over tracked YAML: it inventories every # cert-manager Certificate/Issuer and every Gateway TLS listener wherever they are # authored, and cross-checks each against the issuers and cluster-vars knobs that exist. # A new HTTPRoute/Gateway or a hand-rolled Certificate under apps/ or platform// # attributes no requirement, so requirement-scoped selection would skip the check that # would have caught a listener whose secret nothing ever issues. conformance.home.k3s/scope: "whole-repo" conformance.home.k3s/safety-critical: "false" conformance.home.k3s/executable: "true" conformance.home.k3s/intent: >- Given the tracked tree, when the certificate path is inspected offline, then no manual step exists anywhere in it: serving Secrets are cert-manager-produced, no cert material is committed, every environment's issuer is a tracked ACME issuer with an automated solver and a git-delivered credential, auto-approval is on, and the whole chain is Flux-reconciled. spec: steps: - name: then-no-manual-step-exists-in-the-certificate-path description: >- Run the offline assertion script over the tracked tree (same script ci/l0.sh and conformance/run.sh --layer l0 execute). try: - script: content: bash ./check.sh