openova/platform/cert-manager
hatiyildiz 43aff20254 feat(bp-*): convert all 11 bootstrap-kit charts to umbrella charts depending on upstream
Each platform/<name>/chart/Chart.yaml now declares the canonical upstream
chart as a dependencies: entry. helm dependency build pulls the upstream
payload into the OCI artifact at publish time, so Flux helm install of
bp-<name>:1.1.0 actually installs the upstream Helm release alongside the
Catalyst-curated overlays (NetworkPolicy, ServiceMonitor, ClusterIssuer,
ExternalSecret) under templates/.

Pinned upstream chart versions per platform/<name>/blueprint.yaml:
- cilium                 1.16.5  https://helm.cilium.io
- cert-manager           v1.16.2 https://charts.jetstack.io
- flux                   2.4.0   https://fluxcd-community.github.io/helm-charts
- crossplane             1.17.x  https://charts.crossplane.io/stable
- sealed-secrets         2.16.x  https://bitnami-labs.github.io/sealed-secrets
- spire                  ...     https://spiffe.github.io/helm-charts-hardened
- nats-jetstream         ...     https://nats-io.github.io/k8s/helm/charts
- openbao                ...     https://openbao.github.io/openbao-helm
- keycloak               ...     https://charts.bitnami.com/bitnami
- gitea                  ...     https://dl.gitea.com/charts
- catalyst-platform      umbrella over the 10 leaf bp-* charts via
                         helm dependency

values.yaml in each chart adopts the umbrella convention: catalystBlueprint
metadata block (provenance + version) at top level, upstream subchart
values namespaced under the dependency name.

cert-manager specifically: clusterissuer-letsencrypt-dns01.yaml gets the
helm.sh/hook: post-install,post-upgrade annotation so it applies AFTER
cert-manager controllers are running and CRDs registered (the previous
hollow-chart shape ran the ClusterIssuer at install time when CRDs
didn't exist yet, which was the omantel cluster's exact failure mode).

Wrapper chart version bumped 1.0.0 → 1.1.0 across the board (umbrella
conversion is a meaningful structural revision). Cluster manifests in
clusters/_template/bootstrap-kit/ AND clusters/omantel.omani.works/
bootstrap-kit/ updated to reference 1.1.0.

The blueprint-release.yaml workflow's helm package step needs an
explicit helm dependency build before push so the upstream subchart
bytes ship inside the OCI artifact. That CI change is a follow-up
commit on this same branch (separate file scope).
2026-04-29 17:21:36 +02:00
..
chart feat(bp-*): convert all 11 bootstrap-kit charts to umbrella charts depending on upstream 2026-04-29 17:21:36 +02:00
blueprint.yaml feat(cert-manager): #113 — Lets Encrypt DNS-01 + HTTP-01 ClusterIssuers 2026-04-28 19:44:56 +02:00
README.md docs(pass-8): role-in-Catalyst banners + dead-link fix in component READMEs 2026-04-27 21:39:03 +02:00

cert-manager

TLS certificate automation. Per-host-cluster infrastructure (see docs/PLATFORM-TECH-STACK.md §3.3) — runs on every host cluster a Sovereign owns.

Status: Accepted | Updated: 2026-04-27


Overview

cert-manager provides automated TLS certificate management using Let's Encrypt with automatic renewal and Kubernetes-native integration.


Architecture

flowchart TB
    subgraph CM["cert-manager"]
        Controller[Controller]
        Webhook[Webhook]
        CAInjector[CA Injector]
    end

    subgraph Issuers["Issuers"]
        LE[Let's Encrypt]
        CA[Internal CA]
    end

    subgraph Resources["K8s Resources"]
        Cert[Certificate]
        Secret[TLS Secret]
        Ingress[Gateway/Ingress]
    end

    Controller --> LE
    Controller --> CA
    Cert --> Controller
    Controller --> Secret
    Secret --> Ingress

Challenge Types

Challenge Use Case DNS Provider
HTTP-01 Public endpoints Not required
DNS-01 Wildcards, internal Cloudflare, Route53, etc.

Recommended: DNS-01 for wildcard certificates


Configuration

ClusterIssuer (Let's Encrypt)

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@<domain>
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token
              key: api-token

Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-cert
  namespace: cilium-gateway
spec:
  secretName: wildcard-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - "*.<domain>"
    - "<domain>"

Gateway API Integration

cert-manager integrates with Cilium Gateway API:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: main-gateway
  namespace: cilium-gateway
spec:
  gatewayClassName: cilium
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-tls

Renewal

Setting Value
Renewal window 30 days before expiry
Check interval 24 hours
Retry interval 1 hour on failure

cert-manager automatically renews certificates before expiration.


Monitoring

Metric Description
certmanager_certificate_expiration_timestamp_seconds Certificate expiry time
certmanager_certificate_ready_status Certificate readiness
certmanager_http_acme_client_request_count ACME requests

Part of OpenOva