From c38f77302fe307edd6494239a41121b9864bf245 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Wed, 14 Jan 2026 22:29:27 -0300 Subject: [PATCH] vault: inject comms and grafana secrets --- services/comms/helmrelease.yaml | 152 ++++++++++++++++-- services/comms/kustomization.yaml | 5 + services/comms/scripts/vault-entrypoint.sh | 34 ++++ services/monitoring/helmrelease.yaml | 68 ++++++-- services/monitoring/kustomization.yaml | 6 + .../monitoring/scripts/vault-entrypoint.sh | 34 ++++ 6 files changed, 274 insertions(+), 25 deletions(-) create mode 100644 services/comms/scripts/vault-entrypoint.sh create mode 100644 services/monitoring/scripts/vault-entrypoint.sh diff --git a/services/comms/helmrelease.yaml b/services/comms/helmrelease.yaml index eaa7c20..37eaffb 100644 --- a/services/comms/helmrelease.yaml +++ b/services/comms/helmrelease.yaml @@ -30,6 +30,10 @@ spec: config: publicBaseurl: https://matrix.live.bstein.dev + serviceAccount: + create: false + name: comms-vault + externalPostgresql: host: postgres-service.postgres.svc.cluster.local port: 5432 @@ -71,22 +75,32 @@ spec: limits: cpu: "2" memory: 3Gi - extraEnv: - - name: TURN_SECRET - valueFrom: - secretKeyRef: - name: turn-shared-secret - key: TURN_STATIC_AUTH_SECRET - - name: MAS_SHARED_SECRET - valueFrom: - secretKeyRef: - name: mas-secrets-runtime - key: matrix_shared_secret - - name: MACAROON_SECRET_KEY - valueFrom: - secretKeyRef: - name: synapse-macaroon - key: macaroon_secret_key + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/role: "comms" + vault.hashicorp.com/agent-inject-secret-synapse-env.sh: "kv/data/atlas/comms/synapse-db" + vault.hashicorp.com/agent-inject-template-synapse-env.sh: | + {{ with secret "kv/data/atlas/comms/synapse-db" }} + export POSTGRES_PASSWORD="{{ .Data.data.POSTGRES_PASSWORD }}" + {{ end }} + {{ with secret "kv/data/atlas/comms/synapse-redis" }} + export REDIS_PASSWORD="{{ .Data.data.redis-password }}" + {{ end }} + {{ with secret "kv/data/atlas/comms/turn-shared-secret" }} + export TURN_SECRET="{{ .Data.data.TURN_STATIC_AUTH_SECRET }}" + {{ end }} + {{ with secret "kv/data/atlas/comms/mas-secrets-runtime" }} + export MAS_SHARED_SECRET="{{ .Data.data.matrix_shared_secret }}" + {{ end }} + {{ with secret "kv/data/atlas/comms/synapse-macaroon" }} + export MACAROON_SECRET_KEY="{{ .Data.data.macaroon_secret_key }}" + {{ end }} + vault.hashicorp.com/agent-inject-secret-synapse-signingkey: "kv/data/atlas/comms/othrys-synapse-signingkey" + vault.hashicorp.com/agent-inject-template-synapse-signingkey: | + {{ with secret "kv/data/atlas/comms/othrys-synapse-signingkey" }} + {{ index .Data.data "signing.key" }} + {{ end }} + extraEnv: [] extraCommands: - >- esc() { printf "%s" "$1" | sed "s/'/''/g"; }; @@ -185,6 +199,112 @@ spec: enabled: false existingSecret: othrys-synapse-signingkey existingSecretKey: signing.key + postRenderers: + - kustomize: + patches: + - target: + kind: Deployment + name: othrys-synapse-matrix-synapse + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: othrys-synapse-matrix-synapse + spec: + template: + spec: + serviceAccountName: comms-vault + automountServiceAccountToken: true + containers: + - name: matrix-synapse + command: + - /entrypoint.sh + args: + - sh + - -c + - |- + export POSTGRES_PASSWORD=$(echo "${POSTGRES_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') + export REDIS_PASSWORD=$(echo "${REDIS_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') + cat /synapse/secrets/*.yaml | \ + sed -e "s/@@POSTGRES_PASSWORD@@/${POSTGRES_PASSWORD:-}/" \ + -e "s/@@REDIS_PASSWORD@@/${REDIS_PASSWORD:-}/" \ + > /synapse/config/conf.d/secrets.yaml + + esc() { printf "%s" "$1" | sed "s/'/''/g"; }; + printf '%s\n' \ + "matrix_authentication_service:" \ + " enabled: true" \ + " endpoint: http://matrix-authentication-service:8080/" \ + " secret: '$(esc "${MAS_SHARED_SECRET:-}")'" \ + "turn_shared_secret: '$(esc "${TURN_SECRET:-}")'" \ + "macaroon_secret_key: '$(esc "${MACAROON_SECRET_KEY:-}")'" \ + > /synapse/config/conf.d/runtime-secrets.yaml + + exec python -B -m synapse.app.homeserver \ + -c /synapse/config/homeserver.yaml \ + -c /synapse/config/conf.d/ + env: + - $patch: replace + - name: VAULT_ENV_FILE + value: /vault/secrets/synapse-env.sh + - name: VAULT_COPY_FILES + value: /vault/secrets/synapse-signingkey:/synapse/keys/signing.key + volumeMounts: + - name: comms-vault-entrypoint + mountPath: /entrypoint.sh + subPath: vault-entrypoint.sh + volumes: + - name: comms-vault-entrypoint + configMap: + name: comms-vault-entrypoint + defaultMode: 493 + - name: signingkey + $patch: delete + - name: signingkey + emptyDir: {} + - target: + kind: Deployment + name: othrys-synapse-redis-master + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: othrys-synapse-redis-master + spec: + template: + metadata: + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/role: "comms" + vault.hashicorp.com/agent-inject-secret-redis-env.sh: "kv/data/atlas/comms/synapse-redis" + vault.hashicorp.com/agent-inject-template-redis-env.sh: | + {{ with secret "kv/data/atlas/comms/synapse-redis" }} + export REDIS_PASSWORD="{{ .Data.data.redis-password }}" + {{ end }} + spec: + serviceAccountName: comms-vault + automountServiceAccountToken: true + containers: + - name: redis + command: + - /entrypoint.sh + args: + - /bin/bash + - -c + - /opt/bitnami/scripts/start-scripts/start-master.sh + env: + - $patch: replace + - name: VAULT_ENV_FILE + value: /vault/secrets/redis-env.sh + volumeMounts: + - name: comms-vault-entrypoint + mountPath: /entrypoint.sh + subPath: vault-entrypoint.sh + volumes: + - name: comms-vault-entrypoint + configMap: + name: comms-vault-entrypoint + defaultMode: 493 --- apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease diff --git a/services/comms/kustomization.yaml b/services/comms/kustomization.yaml index b0cc0da..9171b6b 100644 --- a/services/comms/kustomization.yaml +++ b/services/comms/kustomization.yaml @@ -48,6 +48,11 @@ configMapGenerator: - comms_vault_env.sh=scripts/comms_vault_env.sh options: disableNameSuffixHash: true + - name: comms-vault-entrypoint + files: + - scripts/vault-entrypoint.sh + options: + disableNameSuffixHash: true - name: matrix-guest-register files: - server.py=scripts/guest-register/server.py diff --git a/services/comms/scripts/vault-entrypoint.sh b/services/comms/scripts/vault-entrypoint.sh new file mode 100644 index 0000000..fa3b791 --- /dev/null +++ b/services/comms/scripts/vault-entrypoint.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -eu + +if [ -n "${VAULT_ENV_FILE:-}" ]; then + if [ -f "${VAULT_ENV_FILE}" ]; then + # shellcheck disable=SC1090 + . "${VAULT_ENV_FILE}" + else + echo "Vault env file not found: ${VAULT_ENV_FILE}" >&2 + exit 1 + fi +fi + +if [ -n "${VAULT_COPY_FILES:-}" ]; then + old_ifs="$IFS" + IFS=',' + for pair in ${VAULT_COPY_FILES}; do + src="${pair%%:*}" + dest="${pair#*:}" + if [ -z "${src}" ] || [ -z "${dest}" ]; then + echo "Vault copy entry malformed: ${pair}" >&2 + exit 1 + fi + if [ ! -f "${src}" ]; then + echo "Vault file not found: ${src}" >&2 + exit 1 + fi + mkdir -p "$(dirname "${dest}")" + cp "${src}" "${dest}" + done + IFS="$old_ifs" +fi + +exec "$@" diff --git a/services/monitoring/helmrelease.yaml b/services/monitoring/helmrelease.yaml index dbb41ef..470784c 100644 --- a/services/monitoring/helmrelease.yaml +++ b/services/monitoring/helmrelease.yaml @@ -259,6 +259,23 @@ spec: existingSecret: grafana-admin userKey: admin-user passwordKey: admin-password + serviceAccount: + create: false + name: monitoring-vault-sync + automountServiceAccountToken: true + podAnnotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/role: "monitoring" + vault.hashicorp.com/agent-inject-secret-grafana-env.sh: "kv/data/atlas/monitoring/grafana-admin" + vault.hashicorp.com/agent-inject-template-grafana-env.sh: | + {{ with secret "kv/data/atlas/monitoring/grafana-admin" }} + export GF_SECURITY_ADMIN_USER="{{ .Data.data.admin-user }}" + export GF_SECURITY_ADMIN_PASSWORD="{{ .Data.data.admin-password }}" + {{ end }} + {{ with secret "kv/data/atlas/shared/postmark-relay" }} + export GF_SMTP_USER="{{ .Data.data.relay-username }}" + export GF_SMTP_PASSWORD="{{ .Data.data.relay-password }}" + {{ end }} persistence: enabled: true size: 20Gi @@ -300,15 +317,6 @@ spec: hide_version: true users: default_theme: dark - envValueFrom: - GF_SMTP_USER: - secretKeyRef: - name: grafana-smtp - key: username - GF_SMTP_PASSWORD: - secretKeyRef: - name: grafana-smtp - key: password ingress: enabled: true ingressClassName: traefik @@ -429,6 +437,48 @@ spec: mountPath: /etc/grafana/provisioning/alerting configMap: grafana-alerting readOnly: true + postRenderers: + - kustomize: + patches: + - target: + kind: Deployment + name: grafana + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: grafana + spec: + template: + spec: + serviceAccountName: monitoring-vault-sync + automountServiceAccountToken: true + containers: + - name: grafana + command: + - /entrypoint.sh + args: + - /run.sh + env: + - name: GF_SECURITY_ADMIN_USER + $patch: delete + - name: GF_SECURITY_ADMIN_PASSWORD + $patch: delete + - name: GF_SMTP_USER + $patch: delete + - name: GF_SMTP_PASSWORD + $patch: delete + - name: VAULT_ENV_FILE + value: /vault/secrets/grafana-env.sh + volumeMounts: + - name: monitoring-vault-entrypoint + mountPath: /entrypoint.sh + subPath: vault-entrypoint.sh + volumes: + - name: monitoring-vault-entrypoint + configMap: + name: monitoring-vault-entrypoint + defaultMode: 493 --- diff --git a/services/monitoring/kustomization.yaml b/services/monitoring/kustomization.yaml index 6596a36..b12556e 100644 --- a/services/monitoring/kustomization.yaml +++ b/services/monitoring/kustomization.yaml @@ -37,3 +37,9 @@ configMapGenerator: - exporter.py=scripts/jetson_tegrastats_exporter.py options: disableNameSuffixHash: true + - name: monitoring-vault-entrypoint + namespace: monitoring + files: + - scripts/vault-entrypoint.sh + options: + disableNameSuffixHash: true diff --git a/services/monitoring/scripts/vault-entrypoint.sh b/services/monitoring/scripts/vault-entrypoint.sh new file mode 100644 index 0000000..fa3b791 --- /dev/null +++ b/services/monitoring/scripts/vault-entrypoint.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -eu + +if [ -n "${VAULT_ENV_FILE:-}" ]; then + if [ -f "${VAULT_ENV_FILE}" ]; then + # shellcheck disable=SC1090 + . "${VAULT_ENV_FILE}" + else + echo "Vault env file not found: ${VAULT_ENV_FILE}" >&2 + exit 1 + fi +fi + +if [ -n "${VAULT_COPY_FILES:-}" ]; then + old_ifs="$IFS" + IFS=',' + for pair in ${VAULT_COPY_FILES}; do + src="${pair%%:*}" + dest="${pair#*:}" + if [ -z "${src}" ] || [ -z "${dest}" ]; then + echo "Vault copy entry malformed: ${pair}" >&2 + exit 1 + fi + if [ ! -f "${src}" ]; then + echo "Vault file not found: ${src}" >&2 + exit 1 + fi + mkdir -p "$(dirname "${dest}")" + cp "${src}" "${dest}" + done + IFS="$old_ifs" +fi + +exec "$@"