| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- # App secrets (task 46). PLACEHOLDERS ONLY — never commit real values.
- #
- # Consumption: the Deployment and the migrate Job project every key below into
- # a tmpfs volume at `/run/secrets` (`defaultMode: 0400`, group 65532 via the
- # pod `fsGroup`) and read them through `*_FILE` variables, so no secret enters
- # the process environment (`/proc/self/environ`, children, crash dumps,
- # `docker inspect`):
- #
- # token-pepper -> D_OAUTH_TOKEN_PEPPER_FILE
- # totp-encryption-key -> D_OAUTH_TOTP_ENCRYPTION_KEY_FILE
- # pii-encryption-key -> D_OAUTH_PII_ENCRYPTION_KEY_FILE
- # database-password -> D_OAUTH_DATABASE__PASSWORD_FILE
- # redis-password -> D_OAUTH_REDIS__PASSWORD_FILE
- #
- # The PII key is MANDATORY: the server refuses to start without it. Unlike the
- # always-required keys above, the PREVIOUS PII/TOTP keys are OPTIONAL and are
- # projected only during a rotation window; `scripts/check_manifests.py` enforces
- # the mandatory projection and, when a workload references a previous-key
- # `*_FILE`, that its basename is actually projected here.
- #
- # The passwordless DSNs (host/user/db/sslmode and the Redis address) are
- # non-secret and live in `configmap.yaml`; only the passwords are here. A
- # `kubectl exec` into a running pod therefore reads no credential from the
- # environment — only the 0400 files, which the container user already holds.
- # `scripts/check_manifests.py` fails the build if a workload injects any secret
- # through a `secretKeyRef` env instead.
- #
- # In-cluster Redis is expected to run with AUTH (`requirepass`); the password
- # is injected into the bare `redis://host:port` URL at connect time. A Redis
- # deployment without AUTH must enable it, or the workload fails closed on the
- # missing password file.
- #
- # Production rule: this file's keys are replaced by the secret manager
- # (external-secrets / sealed-secrets / vault agent). The manifests only ever
- # reference keys, never values; `scripts/check_manifests.py` fails the build
- # if a placeholder leaks outside this file, if a PEM block appears in any
- # manifest, or if a secret-shaped key lands in the ConfigMap.
- #
- # To provision: `kubectl create secret generic d-oauth-secrets -n d-oauth
- # --from-literal=database-password='...' --from-literal=redis-password='...'
- # ...` (or the external-secret equivalent), then delete this placeholder
- # file from the applied set.
- apiVersion: v1
- kind: Secret
- metadata:
- name: d-oauth-secrets
- namespace: d-oauth
- labels:
- app.kubernetes.io/name: d-oauth-server
- app.kubernetes.io/part-of: d-oauth
- type: Opaque
- stringData:
- # Postgres password, split out of the passwordless DSN in configmap.yaml.
- database-password: "REPLACE_ME__postgres-password"
- # Redis AUTH password, injected into the bare redis:// URL at connect time.
- redis-password: "REPLACE_ME__redis-password"
- # 256-bit server-side pepper for opaque-token hashing. Losing it invalidates
- # every live token; rotate per docs/OPERATIONS.md.
- token-pepper: "REPLACE_ME__at-least-32-bytes-of-random"
- # 256-bit key encrypting TOTP secrets at rest.
- totp-encryption-key: "REPLACE_ME__at-least-32-bytes-of-random"
- # 256-bit master key encrypting PII fields at rest (mandatory). Losing it
- # makes every sealed PII value unreadable; rotate per docs/OPERATIONS.md
- # (retaining the previous key until `pii rotate` completes).
- pii-encryption-key: "REPLACE_ME__at-least-32-bytes-of-random"
|