diff --git a/docs/external-secrets.md b/docs/external-secrets.md
new file mode 100644
index 00000000..683dc0ed
--- /dev/null
+++ b/docs/external-secrets.md
@@ -0,0 +1,38 @@
+
+
+
External Secrets
+
+This document covers how to utilise external secrets and special requirements.
+
+
+* [General](#general)
+* [Components](#components)
+ * [Notes](#notes)
+
+
+# General
+
+For most components when set the external secret will supersede e.g. a password in a `values.yaml` file.
+
+The file [`external_secrets.yaml`](/helmfile/environments/default/external_secrets.yaml.gotmpl) lists all possible references to external secrets that are currently implemented in openDesk.
+
+# Components
+
+This section covers information and special requirements to external secrets that some Helm Charts expect.
+
+## Notes
+
+There are some values that consist of more than just one secret part.
+
+```yaml
+backend:
+ configuration:
+ django:
+ superuserEmail:
+ value: {{ printf "default.admin@%s" .Values.global.domain | quote }}
+ redisUrl:
+ value: "redis://default:{{ .Values.cache.notes.password | default .Values.secrets.redis.password }}@{{ .Values.cache.notes.host }}:{{ .Values.cache.notes.port }}/7"
+```
\ No newline at end of file
diff --git a/helmfile/apps/notes/values.yaml.gotmpl b/helmfile/apps/notes/values.yaml.gotmpl
index 7720c54f..761d388a 100644
--- a/helmfile/apps/notes/values.yaml.gotmpl
+++ b/helmfile/apps/notes/values.yaml.gotmpl
@@ -4,8 +4,14 @@
global:
collaborationServerSecret:
value: {{ .Values.secrets.notes.collaborationSecret | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.collaborationSecret.name | quote }}
+ key: {{ .Values.externalSecrets.notes.collaborationSecret.key | quote }}
yProviderApiKey:
value: {{ .Values.secrets.notes.collaborationSecret | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.collaborationSecret.name | quote }}
+ key: {{ .Values.externalSecrets.notes.collaborationSecret.key | quote }}
fqdn: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}"
tlsSecretName: {{ .Values.ingress.tls.secretName | quote }}
@@ -35,14 +41,23 @@ backend:
ai:
apiKey:
value: {{ .Values.ai.apiKey }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.ai.apiKey.name | quote }}
+ key: {{ .Values.externalSecrets.ai.apiKey.key | quote }}
baseUrl: {{ .Values.ai.endpoint }}
model: {{ .Values.ai.model | quote }}
aws:
endpointUrl: {{ printf "https://%s" (.Values.objectstores.notes.endpoint | default (printf "%s.%s" .Values.global.hosts.minioApi .Values.global.domain)) | quote }}
s3AccessKeyId:
value: {{ .Values.objectstores.notes.username }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.objectstores.notes.s3AccessKeyId.name | quote }}
+ key: {{ .Values.externalSecrets.objectstores.notes.s3AccessKeyId.key | quote }}
s3SecretAccessKey:
value: {{ .Values.objectstores.notes.secretKey | default .Values.secrets.minio.notesUser | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.objectstores.notes.s3SecretAccessKey.name | quote }}
+ key: {{ .Values.externalSecrets.objectstores.notes.s3SecretAccessKey.key | quote }}
storageBucketName: {{ .Values.objectstores.notes.bucket }}
collaboration:
apiUrl: {{ printf "https://%s.%s/collaboration/api/" .Values.global.hosts.notes .Values.global.domain | quote }}
@@ -52,9 +67,15 @@ backend:
name: {{ .Values.databases.notes.name | quote }}
password:
value: {{ .Values.databases.notes.password | default .Values.secrets.postgresql.notesUser | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.databases.notes.password.name | quote }}
+ key: {{ .Values.externalSecrets.databases.notes.password.key | quote }}
port: {{ .Values.databases.notes.port | quote }}
user:
value: {{ .Values.databases.notes.username | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.databases.notes.user.name | quote }}
+ key: {{ .Values.externalSecrets.databases.notes.user.key | quote }}
email:
brandName: "openDesk"
from: "{{ .Values.smtp.localpartNoReply }}@{{ .Values.global.domain }}"
@@ -63,14 +84,23 @@ backend:
logoImage: {{ printf "https://%s.%s/univention/portal/icons/entries/swp.notes.svg" .Values.global.hosts.nubus .Values.global.domain | quote }}
user:
value: {{ printf "%s@%s" "opendesk-system" ( .Values.global.mailDomain | default .Values.global.domain ) }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.postfix.opendeskSystemUsername.name | quote }}
+ key: {{ .Values.externalSecrets.postfix.opendeskSystemUsername.key | quote }}
password:
value: {{ .Values.secrets.postfix.opendeskSystemPassword | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.postfix.opendeskSystemPassword.name | quote }}
+ key: {{ .Values.externalSecrets.postfix.opendeskSystemPassword.key | quote }}
oidc:
enabled: true
rpClientId:
value: "opendesk-notes"
rpClientSecret:
value: {{ .Values.secrets.keycloak.clientSecret.notes | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.keycloak.clientSecret.notes.name | quote }}
+ key: {{ .Values.externalSecrets.keycloak.clientSecret.notes.key | quote }}
opJWKSEndpoint: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/certs"
opAuthorizationEndpoint: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/auth"
opTokenEndpoint: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/token"
@@ -87,14 +117,26 @@ backend:
django:
secretKey:
value: {{ .Values.secrets.notes.djangoSecretKey }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.django.secretKey.name | quote }}
+ key: {{ .Values.externalSecrets.notes.django.secretKey.key | quote }}
createSuperuser: true
superuserEmail:
value: {{ printf "default.admin@%s" .Values.global.domain | quote }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.django.superuserEmail.name | quote }}
+ key: {{ .Values.externalSecrets.notes.django.superuserEmail.key | quote }}
superuserPassword:
value: {{ .Values.secrets.notes.superuser }}
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.django.superuserPassword.name | quote }}
+ key: {{ .Values.externalSecrets.notes.django.superuserPassword.key | quote }}
frontendTheme: "openDesk"
redisUrl:
value: "redis://default:{{ .Values.cache.notes.password | default .Values.secrets.redis.password }}@{{ .Values.cache.notes.host }}:{{ .Values.cache.notes.port }}/7"
+ existingSecret:
+ name: {{ .Values.externalSecrets.notes.redisUrl.name | quote }}
+ key: {{ .Values.externalSecrets.notes.redisUrl.key | quote }}
extraEnvVars:
- name: "FRONTEND_HOMEPAGE_FEATURE_ENABLED"
value: "False"
diff --git a/helmfile/environments/default/external_secrets.yaml.gotmpl b/helmfile/environments/default/external_secrets.yaml.gotmpl
new file mode 100644
index 00000000..327baa2e
--- /dev/null
+++ b/helmfile/environments/default/external_secrets.yaml.gotmpl
@@ -0,0 +1,55 @@
+# SPDX-FileCopyrightText: 2025 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH
+# SPDX-License-Identifier: Apache-2.0
+# The variables set in this file are required to upgrade components to their "Enterprise" product variant.
+---
+externalSecrets:
+ ai:
+ apiKey:
+ name: ~
+ key: ~
+ databases:
+ notes:
+ password:
+ name: ~
+ key: ~
+ user:
+ name: ~
+ key: ~
+ keycloak:
+ clientSecret:
+ notes:
+ name: ~
+ key: ~
+ notes:
+ collaborationSecret:
+ name: ~
+ key: ~
+ django:
+ secretKey:
+ name: ~
+ key: ~
+ superuserEmail:
+ name: ~
+ key: ~
+ superuserPassword:
+ name: ~
+ key: ~
+ redisUrl:
+ name: ~
+ key: ~
+ objectstores:
+ notes:
+ s3AccessKeyId:
+ name: ~
+ key: ~
+ s3SecretAccessKey:
+ name: ~
+ key: ~
+ postfix:
+ opendeskSystemPassword:
+ name: ~
+ key: ~
+ opendeskSystemUsername:
+ name: ~
+ key: ~
+...