OAK OpenBao: add HTTPS and Let's Encrypt support

Part 2 of !9289 (merged).

When oak['components']['openbao']['external_url'] uses https://, the NGINX reverse proxy now:

  • Listens with ssl and configures ssl_certificate / ssl_certificate_key (derived from the FQDN by default, or user-supplied).
  • Optionally redirects HTTP→HTTPS (set automatically when Let's Encrypt is enabled, otherwise opt-in via redirect_http_to_https).
  • Serves the ACME /.well-known/acme-challenge/ path from both the redirect and main server blocks so Let's Encrypt HTTP-01 validation works.

When letsencrypt['enable'] is true and no cert file exists yet, the OpenBao FQDN is added as a SAN to the main Let's Encrypt certificate (same approach used by KAS, Registry, and Mattermost), and the cert paths are shared with the main GitLab certificate.

GCP E2E validation (real Let's Encrypt)

Validated end-to-end on a GCP VM (e2-standard-4, Ubuntu 24.04) with real Let's Encrypt certificates. Test scripts and instructions are at oak/openbao-ssl-gcp/.

All 5 checks passed :

  • listen 443 ssl present in the rendered NGINX config
  • LE cert SANs include both gitlab.oak.jcunha.dev and openbao.oak.jcunha.dev
  • curl https://openbao.oak.jcunha.dev/v1/sys/health{"initialized":true,"sealed":false,...}
  • curl -I http://openbao.oak.jcunha.dev/301 Moved Permanently
  • curl -I http://openbao.oak.jcunha.dev/.well-known/acme-challenge/test-token404 (not 301)

Note for implementors — gitlab_rails['openbao']['internal_url']: In the GCP test setup, Rails must use the ClusterIP of the openbao-active Kubernetes Service (e.g. http://10.43.170.146:8200) for internal_url, not http://127.0.0.1:8200. This applies only to internal_url (the URL Rails uses for direct OpenBao API calls); the external_url is unaffected. The reason: Klipper routes all *:8200 host traffic through the Envoy Gateway pod, which only forwards requests whose Host header matches the OpenBao domain — requests from Rails with Host: 127.0.0.1:8200 are rejected with 404. Pointing internal_url at the openbao-active Service ClusterIP bypasses Envoy entirely; kube-proxy DNATs the traffic straight to the OpenBao pod. The test scripts handle this automatically by reading the Service ClusterIP after Helm deploy and appending it to gitlab.rb.

Edited by João Alexandre Cunha

Merge request reports

Loading