# tenants-wildcard injected Secret(s) — Slice 2B.3 (2026-05-04). # # This template is the "Restore" half of the Vault Stash/Restore # flow. Tower harvests successfully-issued wildcard cert Secrets # into per-tenant Vault paths (`v3/tenants//certificates/`). # On Reconnect for the same tenant + root, Tower reads the stash back # and passes it as helm values: # # certManager.injectedWildcards: # - root: "acme.com" # primary: true # mirrors tenant.domains[i].primary # crt: "" # key: "" # # When an entry is present, this file emits a kubernetes.io/tls # Secret with the SAME name the cert-manager Certificate path would # have produced — so existing IngressRoutes and per-instance # references don't have to change to use the injected variant. # # tenants-wildcard-cert.yaml's matching skip-condition keeps the # Certificate resource from rendering for the same root, so no # ACME order is placed and the Let's Encrypt rate-limit budget is # preserved across reconnect churn. # # Naming contract (must mirror tenants-wildcard-cert.yaml exactly): # primary → `tenants-wildcard-tls` # non-primary → `tenants-wildcard--tls` # # Empty / missing fields on an entry → silently skip that entry. # Tower is responsible for populating crt + key + root before passing # the entry through; a half-formed entry shouldn't render a broken # Secret that would mask the real ACME path. {{- range .Values.certManager.injectedWildcards | default (list) }} {{- if and .root .crt .key }} {{- $suffix := "" }} {{- if not .primary }} {{- $suffix = printf "-%s" (replace "." "-" .root) }} {{- end }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "tenants-wildcard%s-tls" $suffix | quote }} namespace: tenants labels: app.kubernetes.io/managed-by: cluster-platform-v3 odoosky.io/domain-root: {{ .root | quote }} odoosky.io/wildcard-source: vault-injected {{- if .primary }} odoosky.io/domain-primary: "true" {{- end }} annotations: # Wave 2 to land in the same step as the (skipped) Certificate # resource would have. Keeps the substrate-Ready timing model # identical between ACME-issued and injected paths. argocd.argoproj.io/sync-wave: "2" type: kubernetes.io/tls data: tls.crt: {{ .crt | b64enc | quote }} tls.key: {{ .key | b64enc | quote }} {{- end }} {{- end }}