Skip to main content

Platform secrets

Third-party services read their credentials from Kubernetes Secrets created by External Secrets (deploy/external-secrets/secrets, Argo CD component platform-secrets). No value is committed.

Bootstrap order​

  1. cert-manager creates the internal root CA (cert-manager/eai-root-ca, deploy/cert-manager/cluster-issuers.yaml); the OpenBao TLS certificate is issued by that CA.
  2. OpenBao is initialised and unsealed (bao operator init, bao operator unseal), then deploy/openbao/bootstrap.sh enables KV v2 (kv), transit, kubernetes auth and the policies.
  3. The operator writes every entry of the table below: bao kv put kv/eai/platform/<namespace>/<secret> <property>=<value> ....
  4. Argo CD applies platform-secrets: the ClusterSecretStore openbao (deploy/openbao/k8s/clustersecretstore.yaml) syncs the ExternalSecrets (refresh 1h, creationPolicy: Owner, deletionPolicy: Retain).
  5. The Secret kyverno/cosign-public-key (key cosign.pub) comes from the Terraform module platform-bootstrap (variable cosign_public_key), because admission needs it before anything else.

OpenBao entries​

OpenBao path (kv)PropertiesConsumerHow to generate
eai/platform/apisix/redis-acl-apisixapisix-passwordapisix/redis-acl-apisix: APISIX (limit-count Redis)openssl rand -base64 32; its sha256 goes into user.acl (user apisix)
eai/platform/eai-data/nats-userscontrol-plane, multimodal, workereai-data/nats-users: NATS (bcrypt hashes)bcrypt of openssl rand -base64 32: nats server passwd -p <password>
eai/platform/eai-data/redis-acluser.acleai-data/redis-acl: Redis (whole ACL file, deploy/data/redis/values.yaml)the ACL file with #<sha256> per user: printf %s <password> | sha256sum
eai/platform/eai-data/redis-passwordpasswordeai-data/redis-password: Redis default user (operator and replication only)openssl rand -base64 32
eai/platform/eai-data/redis-opik-acluser.acleai-data/redis-opik-acl: Redis dedicated to Opik (ACL file, deploy/data/redis-opik/values.yaml)the ACL file with #<sha256> per user: printf %s <password> | sha256sum
eai/platform/eai-data/redis-opik-passwordpasswordeai-data/redis-opik-password: Redis dedicated to Opik, default user (operator and replication only)openssl rand -base64 32
eai/platform/eai-data/cnpg-s3ACCESS_KEY_ID, SECRET_ACCESS_KEYeai-data/cnpg-s3: CloudNativePG backups (bucket eai-backups, prefix cnpg)keys of an S3 user limited to the eai-backups bucket
eai/platform/velero/velero-s3cloudvelero/velero-s3: Velero (AWS credentials file format)[default] section with aws_access_key_id and aws_secret_access_key of an S3 user limited to the Velero bucket
eai/platform/eai-data/qdrant-api-keyapi-key, read-only-api-keyeai-data/qdrant-api-key: Qdrant (control plane, workers)openssl rand -base64 32 each
eai/platform/eai-data/temporal-db-credentialsusername, passwordeai-data/temporal-db-credentials: Temporal (Postgres role temporal)username temporal; openssl rand -base64 32, same as the CloudNativePG role
eai/platform/eai-data/livekit-keysapi-key, api-secreteai-data/livekit-keys: LiveKit, same pair as EAI_LIVEKIT_API_KEY / EAI_LIVEKIT_API_SECRET of the control planeapi-key: openssl rand -hex 8; api-secret: openssl rand -base64 48 (at least 32 bytes)
eai/platform/eai-data/livekit-redispasswordeai-data/livekit-redis: LiveKit (Redis ACL user livekit)openssl rand -base64 32; its sha256 goes into user.acl
eai/platform/eai-security/keycloak-bootstrap-adminusername, passwordeai-security/keycloak-bootstrap-admin: Keycloak (temporary admin)openssl rand -base64 32
eai/platform/eai-security/keycloak-dbusername, passwordeai-security/keycloak-db: Keycloak (Postgres role keycloak)openssl rand -base64 32
eai/platform/eai-security/openfga-dburieai-security/openfga-db: OpenFGApostgres://openfga:<password>@eai-postgres-rw.eai-data.svc:5432/openfga?sslmode=verify-full&sslrootcert=/etc/openfga/db-ca/ca.crt
eai/platform/eai-security/openfga-presharedkeyseai-security/openfga-preshared: OpenFGA (also EAI_OPENFGA_API_TOKEN)openssl rand -base64 32, comma separated
eai/platform/observability/clickhouse-operator-accessusername, passwordobservability/clickhouse-operator-access: ClickHouse operator (metrics, schema)username clickhouse_operator; openssl rand -base64 32
eai/platform/observability/clickhouse-userseai-reader, eai-writer, opikobservability/clickhouse-users: ClickHouse (sha256 hex digests)printf %s <password> | sha256sum (the plain password of opik goes to clickhouse-credentials and opik-backend-credentials)
eai/platform/observability/otel-opensearchpasswordobservability/otel-opensearch: OpenTelemetry Collector (OpenSearch user otel-writer, logs)openssl rand -base64 32
eai/platform/observability/opensearch-internal-usersinternal_users.ymlobservability/opensearch-internal-users: OpenSearch (security plugin users, bcrypt hashes)plugins/opensearch-security/tools/hash.sh -p <password> for each user
eai/platform/observability/opensearch-bootstrappasswordobservability/opensearch-bootstrap: opensearch-bootstrap Job (index templates, ISM, Security Analytics)openssl rand -base64 32
eai/platform/observability/jaeger-opensearchpassword, ca.crtobservability/jaeger-opensearch: Jaeger (OpenSearch user jaeger, span storage)openssl rand -base64 32; ca.crt of eai-root-ca
eai/platform/observability/opik-backend-credentialsSTATE_DB_PASS, ANALYTICS_DB_PASS, ANALYTICS_DB_MIGRATIONS_PASS, REDIS_URL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYobservability/opik-backend-credentials: Opik (client provided MySQL, ClickHouse opik, redis-opik, S3 bucket opik)MySQL password of the client; plain password of opik; rediss://opik:<password>@redis-opik-master.eai-data.svc.cluster.local:6379/0; S3 user of the object store
eai/platform/observability/clickhouse-credentialspasswordobservability/clickhouse-credentials: Opik (adminUser of ClickHouseInstallation opik-clickhouse)plain password of opik
eai/platform/observability/otel-clickhousepasswordobservability/otel-clickhouse: OpenTelemetry Collector (ClickHouse otel)openssl rand -base64 32
eai/platform/observability/alertmanager-webhooksdefault-url, oncall-url, finops-url, security-urlobservability/alertmanager-webhooks: Alertmanager receiverswebhook URLs of the on-call tools
eai/platform/spire-server/spire-server-dbpasswordspire-server/spire-server-db: SPIRE server (Postgres role spire)openssl rand -base64 32

CA copies​

Public certificates (key ca.crt only, never tls.key) are copied by the External Secrets kubernetes provider (deploy/external-secrets/secrets/ca-stores.yaml): eai-root-ca to apisix, observability and eai-data (eai-internal-ca) and to spire-server (openbao-ca); the CloudNativePG CA eai-data/eai-postgres-ca to eai-security and spire-server. Each store has its own ServiceAccount and a Role limited to get on the source Secret.