Files
bluejay-infra/gated/public-tls/README.md
Andrew Stoltz 387097485e infra(public-tls): add gated Let's Encrypt issuers + tenant NetworkPolicy substrate
Cl-infra-2 (deep-regroup 2026-06-13). LE staging+prod ClusterIssuers (HTTP-01
via Traefik, DNS-01 stub) + a per-tenant default-deny NetworkPolicy template,
under gated/public-tls/ OUTSIDE apps/ so the ApplicationSet does NOT auto-apply
them (an applied ACME ClusterIssuer registers an account immediately). Internal
*.iamworkin.lan TLS stays on step-ca. Inert until the operator opens the
web-hosting public-exposure gate (R-1; 14/14 blockers red). Pairs with Codex
Wh-C1 (hybrid public TLS) + Wh-C2 (isolation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:06:31 -05:00

2.2 KiB

Public-TLS substrate (gated)

Lane: Cl-infra-2 (deep-regroup 2026-06-13). Status: authored, NOT applied — operator-gated.

This directory holds the Let's Encrypt + isolation substrate for public multi-tenant web hosting. It lives outside apps/ on purpose: the bluejay-infra ApplicationSet only reconciles apps/*, so nothing here is auto-applied. Applying a cert-manager ACME ClusterIssuer registers an ACME account immediately, so these stay inert until the operator opens the web-hosting public-exposure gate (R-1).

What's here

File What Activate when
letsencrypt-issuers.yaml letsencrypt-staging + letsencrypt-prod ClusterIssuers (HTTP-01 via Traefik; DNS-01 stub for wildcards) Public-go. Move to apps/cluster-issuers/, staging first.
tenant-networkpolicy-template.yaml Per-tenant default-deny + allowlist NetworkPolicy (Traefik ingress, CoreDNS, own-DB egress only) Rendered per tenant at provision time (Wh-C2 isolation).

The gate

Public exposure is NO-GO until the §6 go/no-go checklist in docs/standards/web-hosting-production-readiness-plan.md is green (currently 14/14 red) and the operator explicitly opens R-1. Internal *.iamworkin.lan TLS stays on step-ca (apps/fc-dns/fc-dns.yamlstep-ca-dns01); these LE issuers are only for public tenant domains.

Pairing

  • Codex Wh-C1 consumes letsencrypt-staging/-prod for hybrid public TLS on FlowerCore.PHP/MySQL/DNS.
  • Codex Wh-C2 consumes the NetworkPolicy template for cross-tenant isolation suites.

Activation checklist (public-go)

  1. Wire a public DNS-01 solver (Cloudflare/Namecheap webhook) or confirm public tenant domains route HTTP-01 to the cluster ingress.
  2. git mv gated/public-tls/letsencrypt-issuers.yaml apps/cluster-issuers/ — staging only.
  3. Issue one staging cert for a throwaway public domain; verify the chain in a browser.
  4. Flip that tenant's Certificate issuerRef to letsencrypt-prod; mind LE rate limits.
  5. Render tenant-networkpolicy-template.yaml per tenant; run the Wh-C2 negative suites.