/goal /ultracode-workflows [POL-4] policy-govern the secrets + domains + network invariants #42

Closed
opened 2026-07-01 02:03:51 +00:00 by plat · 2 comments
Owner

Track/Wave: POL-4 · Wave G5 · Size M
Repos: gitops
Depends on: POL-1, SEC-1, DOM-1a, DOM-2

Why

Secrets/domains/network become continuously-enforced invariants (not enforced-by-convention at germinate time) so no plaintext Secret, mis-scoped env, unregistered host, or blanket-egress app can ever be applied.

Scope

Kyverno ClusterPolicies: reject any raw Secret not from the sops flow; require app env secrets in ----{prod,dev} with expected labels (accept a rotated-but-sealed secret); Ingress host must be a registered/verified domain or a platform host; every app namespace must carry a scoped CiliumNetworkPolicy (reject blanket-only egress).

Acceptance

Applying a plaintext Secret is rejected; a sops-sealed app secret in the correct namespace admits (including after an age-key rotation); an Ingress with an unregistered host is rejected; a blanket-egress app is rejected while a scoped-CiliumNetworkPolicy app admits; cert-manager ACME still issues certs under the policy.

Notes

HAZARD: must NOT block cert-manager's ACME DNS-01 egress (shared with DOM-2). Adds distinct policy files; shares only the kyverno kustomization include line.


Part of the First Client Deploy → Governance roadmap. The owning agent may recurse into its own subagent team (ultracode workflow) if the task warrants. Honor the seam-serialization: land on a shared seam by rebase, and don't start a seam position until the prior one has merged.

**Track/Wave:** `POL-4` · Wave **G5** · Size **M** **Repos:** `gitops` **Depends on:** POL-1, SEC-1, DOM-1a, DOM-2 ## Why Secrets/domains/network become continuously-enforced invariants (not enforced-by-convention at germinate time) so no plaintext Secret, mis-scoped env, unregistered host, or blanket-egress app can ever be applied. ## Scope Kyverno ClusterPolicies: reject any raw Secret not from the sops flow; require app env secrets in <owner>--<app>--{prod,dev} with expected labels (accept a rotated-but-sealed secret); Ingress host must be a registered/verified domain or a platform host; every app namespace must carry a scoped CiliumNetworkPolicy (reject blanket-only egress). ## Acceptance Applying a plaintext Secret is rejected; a sops-sealed app secret in the correct namespace admits (including after an age-key rotation); an Ingress with an unregistered host is rejected; a blanket-egress app is rejected while a scoped-CiliumNetworkPolicy app admits; cert-manager ACME still issues certs under the policy. ## Notes **HAZARD: must NOT block cert-manager's ACME DNS-01 egress (shared with DOM-2). Adds distinct policy files; shares only the kyverno kustomization include line.** --- *Part of the **First Client Deploy → Governance** roadmap. The owning agent may recurse into its own subagent team (ultracode workflow) if the task warrants. Honor the seam-serialization: land on a shared seam by rebase, and don't start a seam position until the prior one has merged.*
Author
Owner

Enforce-flip prepared (POL-4 half): plat/gitops#14 — default-off, reviewable, NOT merged.

  • The flip is a kustomize Component (kyverno-policies/enforce/); the operator activates it with one include line (components: [enforce]) — or a later germinate PLAT_POL_ENFORCE=1 can wire the same line. Until then germination behavior is provably unchanged (default render byte-identical to main, ± one Audit bug fix).
  • POL-4 calls: disallow-unmanaged-secrets safe-now after fixing a real gap found on a live daughter — wildcard-plat-tls (cert-manager renews it per app ns) was missing from the allowlist, so Enforce would have broken TLS renewals; require-registered-ingress-host safe-now (fork correctly rewrites the domain allow-list — verified live); the network invariant is already continuously enforced by the POL-2 generate policies (synchronize: true), no flip needed.
  • failurePolicy goes Fail (POL-0 fail-closed-bounded) on the namespaced-kind policies, with the bounding conditions shipped in the same include: HA admission controller (3 replicas + PDB) + plat.sh/break-glass namespace hatch, via an optional: true valuesFrom that is inert while the component is off.
  • Also fixed on main (default-safe): the reports-controller couldn't read Secrets at all — POL-4's secrets policy produced zero background PolicyReport entries; audit-first was blind here until now.
  • Validated: offline kyverno apply v1.18.1 (= live engine) 16-case matrix (plaintext Secret denied, platform Secrets admit, squat host denied, …), render diffs exact, server-side dry-run green on the local k3d daughter. Pre-flip checklist in ENFORCE.md: disposable germination with the component active + POL-0 kill-the-webhook test.

The trigger is safe to pull; pulling it stays an operator decision.

**Enforce-flip prepared (POL-4 half): plat/gitops#14 — default-off, reviewable, NOT merged.** - The flip is a kustomize Component (`kyverno-policies/enforce/`); the operator activates it with **one include line** (`components: [enforce]`) — or a later germinate `PLAT_POL_ENFORCE=1` can wire the same line. Until then germination behavior is provably unchanged (default render byte-identical to main, ± one Audit bug fix). - POL-4 calls: `disallow-unmanaged-secrets` **safe-now** after fixing a real gap found on a live daughter — `wildcard-plat-tls` (cert-manager renews it per app ns) was missing from the allowlist, so Enforce would have broken TLS renewals; `require-registered-ingress-host` **safe-now** (fork correctly rewrites the domain allow-list — verified live); the network invariant is already continuously enforced by the POL-2 generate policies (`synchronize: true`), no flip needed. - failurePolicy goes **Fail** (POL-0 fail-closed-bounded) on the namespaced-kind policies, with the bounding conditions shipped in the same include: HA admission controller (3 replicas + PDB) + `plat.sh/break-glass` namespace hatch, via an `optional: true` valuesFrom that is inert while the component is off. - Also fixed on main (default-safe): the reports-controller couldn't read Secrets at all — POL-4's secrets policy produced **zero** background PolicyReport entries; audit-first was blind here until now. - Validated: offline `kyverno apply` v1.18.1 (= live engine) 16-case matrix (plaintext Secret denied, platform Secrets admit, squat host denied, …), render diffs exact, server-side dry-run green on the local k3d daughter. Pre-flip checklist in `ENFORCE.md`: disposable germination with the component active + POL-0 kill-the-webhook test. The trigger is safe to pull; pulling it stays an operator decision.
Author
Owner

Enforce flip DONE + live (2026-07-06), with 2 bugs found & fixed

The Audit→Enforce flip (components: [enforce]) is merged to plat/gitops main (PR #15, on top of #14) and captured in the genesis seed r41, so every future germination + the nightly gate now carry Enforce. Verified live on the product-garden.com granddaughter: admission controller 3 replicas (HA), 11 validate rules at Enforce, plaintext-Secret / unregistered-host / public-image all denied.

Pre-flight (qa-d1) + this real-VPS app run surfaced 3 issues, all handled:

  1. PR#14 ConfigMap was half-inert — Flux merges spec.values OVER valuesFrom, so the enforce ConfigMap's replicas/namespaceSelector never landed. Fixed inline in the kyverno HelmRelease (PR #15).
  2. ENFORCE.md kill-test was fail-OPEN — a graceful scale --replicas=0 makes Kyverno delete its own webhooks; rewrote it to a crash-style kill (PR #15).
  3. Enforce broke ALL app TLS (#91) — disallow-unmanaged-secrets blocked cert-manager's issuance temporaries (wildcard-plat-tls-<rand>). Fixed with a glob allowlist (gitops#17). This is why the flip must not go onto a live app-serving platform without the fix — the current ENFORCE.md pre-flight doesn't deploy a real app+TLS.

Enforce is delivered. Closing #42/#43; residual hardening (ENFORCE.md checklist gap) tracked in #91.

## Enforce flip DONE + live (2026-07-06), with 2 bugs found & fixed The Audit→Enforce flip (`components: [enforce]`) is merged to **plat/gitops main** (PR #15, on top of #14) and captured in the **genesis seed r41**, so every future germination + the nightly gate now carry Enforce. Verified live on the `product-garden.com` granddaughter: admission controller **3 replicas** (HA), 11 validate rules at Enforce, plaintext-Secret / unregistered-host / public-image all **denied**. Pre-flight (qa-d1) + this real-VPS app run surfaced 3 issues, all handled: 1. **PR#14 ConfigMap was half-inert** — Flux merges `spec.values` OVER `valuesFrom`, so the enforce ConfigMap's replicas/namespaceSelector never landed. Fixed inline in the kyverno HelmRelease (PR #15). 2. **ENFORCE.md kill-test was fail-OPEN** — a graceful `scale --replicas=0` makes Kyverno delete its own webhooks; rewrote it to a crash-style kill (PR #15). 3. **Enforce broke ALL app TLS** (#91) — `disallow-unmanaged-secrets` blocked cert-manager's issuance temporaries (`wildcard-plat-tls-<rand>`). Fixed with a glob allowlist (gitops#17). **This is why the flip must not go onto a live app-serving platform without the fix** — the current ENFORCE.md pre-flight doesn't deploy a real app+TLS. Enforce is delivered. Closing #42/#43; residual hardening (ENFORCE.md checklist gap) tracked in #91.
plat closed this issue 2026-07-06 19:24:09 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
open-platform/mitosis#42
No description provided.