# One ExternalSecret per Kubernetes Secret that was previously created by hand. # # These REPLACE the hand-applied secret.yaml files in ../../apps/authelia, ../../apps/gitea and # ../../infrastructure/cloudflared. Those files stay gitignored as the break-glass copy — if OpenBao # is down during a rebuild you can still `kubectl apply -f /secret.yaml` and # carry on. ESO will reconcile back over it once bao returns. # # ⚠ ESO takes OWNERSHIP of the target Secret. The existing hand-created Secrets have # the same names on purpose, so ESO adopts rather than duplicates them — but that # also means a wrong key name here will OVERWRITE a working Secret with an empty or # partial one. Check `kubectl get externalsecret -A` reports SecretSynced before # trusting it, and remember Authelia and Gitea only read their secrets at startup. # # refreshInterval is deliberately long. Nothing here rotates on its own yet, and a # short interval only adds load plus a wider window to notice a bad sync. When the # OpenBao PostgreSQL secrets engine lands (see ../docs/cicd.md) the rotating # credentials will want a shorter interval AND something to restart the consumer. --- apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: authelia-secrets namespace: authelia spec: refreshInterval: 1h secretStoreRef: name: openbao kind: ClusterSecretStore target: name: authelia-secrets creationPolicy: Owner # extract pulls EVERY key at the path, so the six key names live in OpenBao # rather than being restated here. They must match the `path:` values in # ../../apps/authelia/values.yaml exactly. dataFrom: - extract: key: k8s/authelia --- # Separate Secret, not a seventh key in authelia-secrets — the chart projects the # existingSecret volume with an explicit items: list of only the six keys it # generates, so an extra key would be stored but never mounted. That mistake took # SSO down on 2026-07-28. apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: authelia-oidc-jwks namespace: authelia spec: refreshInterval: 1h secretStoreRef: name: openbao kind: ClusterSecretStore target: name: authelia-oidc-jwks creationPolicy: Owner dataFrom: - extract: key: k8s/authelia-oidc-jwks --- apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: gitea-db namespace: gitea spec: refreshInterval: 1h secretStoreRef: name: openbao kind: ClusterSecretStore target: name: gitea-db creationPolicy: Owner dataFrom: - extract: key: k8s/gitea --- apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: cloudflared-tunnel namespace: cloudflared spec: refreshInterval: 1h secretStoreRef: name: openbao kind: ClusterSecretStore target: name: cloudflared-tunnel creationPolicy: Owner dataFrom: - extract: key: k8s/cloudflared --- # SeaweedFS S3 identities, including the least-privilege `terraform` identity that # holds Terraform remote state. # # ⚠ These credentials were previously INLINE in ../../apps/seaweedfs/values.yaml and went # into git with the initial commit. Externalising stops the bleeding; the leaked # anvAdmin key still needs rotating separately, since it is in history. # # The chart normally GENERATES seaweedfs-s3-secret from s3.credentials. We point # filer.s3.existingConfigSecret at this one instead, so the chart stops rendering # credentials from values entirely. # zot 的 AK/SK 只保存在 k8s/zot-s3;在此组装服务端配置,不在基础配置中维护副本。 apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: seaweedfs-s3-config namespace: seaweedfs spec: refreshInterval: 1h secretStoreRef: name: openbao kind: ClusterSecretStore target: name: seaweedfs-s3-config creationPolicy: Owner template: engineVersion: v2 mergePolicy: Replace data: seaweedfs_s3_config: |- {{- $config := mustFromJson .baseConfig -}} {{- if not (kindIs "slice" $config.identities) -}} {{- fail "base S3 configuration must contain an identities array" -}} {{- end -}} {{- if or (eq .zotAccessKey "") (eq .zotSecretKey "") -}} {{- fail "zot S3 credentials must not be empty" -}} {{- end -}} {{- $identities := list -}} {{- range $config.identities -}} {{- if ne .name "zot" -}} {{- $identities = append $identities . -}} {{- end -}} {{- end -}} {{- $credential := dict "accessKey" .zotAccessKey "secretKey" .zotSecretKey -}} {{- $zot := dict "name" "zot" "credentials" (list $credential) "actions" (list "Read:zot" "Write:zot" "List:zot" "Tagging:zot") -}} {{- $_ := set $config "identities" (append $identities $zot) -}} {{- mustToJson $config -}} data: - secretKey: baseConfig remoteRef: key: k8s/seaweedfs-s3 property: seaweedfs_s3_config - secretKey: zotAccessKey remoteRef: key: k8s/zot-s3 property: access_key - secretKey: zotSecretKey remoteRef: key: k8s/zot-s3 property: secret_key