Reading it from the cluster¶
External Secrets Operator runs in the controllers layer
(flux/20_controllers/external-secrets/). It has no deploy-time dependency on
OpenBao — it only talks to it when an ExternalSecret reconciles, and retries
until it answers. Each consuming namespace ships its own ServiceAccount +
SecretStore + ExternalSecret alongside the app in flux/50_apps/<app>/. A
SecretStore is namespaced, and that is the point: a ClusterSecretStore would
authenticate as one identity for everyone and dissolve the per-namespace
boundary this root builds.
apiVersion: v1
kind: ServiceAccount
metadata:
name: seaweedfs
namespace: observability
---
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: seaweedfs
namespace: observability
spec:
provider:
vault:
server: http://openbao-active.openbao.svc:8200
path: seaweedfs
version: v2
auth:
kubernetes:
mountPath: kubernetes
role: seaweedfs-observability
serviceAccountRef:
name: seaweedfs
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: loki-s3
namespace: observability
spec:
refreshInterval: 1h
secretStoreRef:
name: seaweedfs
kind: SecretStore
target:
name: loki-s3
data:
- secretKey: S3_ACCESS_KEY_ID
remoteRef:
key: observability/loki
property: access_key_id
- secretKey: S3_SECRET_ACCESS_KEY
remoteRef:
key: observability/loki
property: secret_access_key
The vault provider path is the kv-v2 mount this root owns, and the role is
the per-namespace Kubernetes auth role from Which mount. The KV keys
(observability/loki, observability/mimir, observability/tempo) and their
properties (access_key_id, secret_access_key) did not change at the cutover;
only the store, the ServiceAccount and the role were renamed.
Only the two key fields are pulled. bucket, endpoint and region also sit in
the KV entry, but they are not secrets and the charts carry them in values;
dataFrom.extract would copy all five into the Secret if an app wanted that.
Buckets are addressed path-style — endpoint carries no bucket, and clients
must set force_path_style (boto3: addressing_style = "path") with region
us-east-1.
The endpoint stored in KV is http://s3.gewis.nl:8333, a name the cluster
resolver answers from the hosts block in flux/40_services/dns/corefile.yaml. It
is deliberately not the raw address: s3-01 holds a DHCP lease, and every
consumer reading this KV entry runs inside the cluster. The
seaweedfs_endpoint default used by tofu stays an address, because it runs on
a workstation that resolves through campus DNS, which knows nothing about that
name.