feat(forgejo): record the CNPG-generated database password

forgejo-db-app is owned by the Cluster CR and was generated by CNPG: there is no
bootstrap secret, so nothing outside cloudnative-pg ever knew that password.

CNPG reads spec.bootstrap.initdb.secret only at creation. Recreate the Cluster CR and
CNPG mints a new password while the data directory keeps the old one — Forgejo starts,
stays Ready, and fails every query. That is a credential fault wearing a network fault's
clothes, and it is exactly the shape of tonight's outage.

This file is the record. Point spec.bootstrap.initdb.secret at it when the cluster is
rebuilt. The value matches the live Secret today; verified by decrypting and comparing.
This commit is contained in:
2026-10-28 03:14:38 -07:00
parent 15a22abb1f
commit 695f03a0ab
@@ -0,0 +1,39 @@
# Bootstrap credential for the Forgejo database — the one secret in the CNPG path
# that the cluster can lose without any controller to recreate it.
#
# forgejo-db-app is OWNED by the Cluster CR (ownerReferences: Cluster/forgejo-db,
# managed-by: cloudnative-pg) and was GENERATED by CNPG: spec.bootstrap.initdb.secret
# is empty, so nothing but cloudnative-pg ever knew this value.
#
# CNPG reads spec.bootstrap.initdb.secret ONLY at cluster creation. So if the Cluster
# CR is ever deleted and recreated, CNPG mints a new password while the data directory
# on the PVC keeps the old one. Forgejo then starts, stays Ready, and fails every
# query — a credential fault that looks like a network fault. This file is the record
# that makes a rebuild reproducible: point spec.bootstrap.initdb.secret at it.
#
# Keep this file. It cannot rotate on its own; rotation is a manual CNPG ALTER ROLE
# followed by updating this file and the Secret.
apiVersion: v1
kind: Secret
metadata:
name: forgejo-db-bootstrap
namespace: cicd
type: kubernetes.io/basic-auth
stringData:
username: ENC[AES256_GCM,data:GFRjVvq3iQ==,iv:7ZxKdHTvKt6TYlsQYu57dt9C14h59xyfrL3+o/deon0=,tag:Ame/mfgDlHk1oPp80hE3LQ==,type:str]
password: ENC[AES256_GCM,data:11t2yglSWQGKeMQ0ZRaw3L5s/o3iHEYArFWdfAQBYSnz1SMOmZ2XTl9yDDHFMUEgHK4K4mP4fJaq4nsgfgr5pA==,iv:aCQ4nkuUX6jDNiOsRW5nzST7HgNZmhjRidmskfNArAg=,tag:ddN0lf+7i4LpS6+yK+za+A==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3ZVQzajgzcmE2MnFzb1pJ
VFR4NjNtU2lWYjZGdGNuOVVnTkNxRndadXhzCkhrU3pPZi9NUlRkRWNUdHNKbW9a
WTcvVnVRM2tWZE1OMDBGcTd0NjhzeVkKLS0tIG5PQlg3ZlBNMDhQV2hxdzB4K1g3
SHBtZ284bTJNV3FvSWFtbDRudGUzbTQKNPM04xB1DWyIE/6/qjUCvXw2M8zkhVkP
xV8bVIp81R0pnMuEGB60L38W81SfziSspzpU0YMUmgZcU2XmO73AdQ==
-----END AGE ENCRYPTED FILE-----
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
encrypted_regex: ^(data|stringData)$
lastmodified: "2026-10-28T10:09:09Z"
mac: ENC[AES256_GCM,data:oNYDrN9wzVbDrDTYcLEKwCqTruybeU+++58Duki5P8xddU1anjHzfBg9DXgXd6CaoYJAU2jEcrqX9YXN8zmJtGaTpgr2GUdgFWx6O1JFoaNM32RNcp7u8FZWpcFYecWyYRtRFMolRaLM/CxkXr2lLa/V3Azxe1xlJrf7EjyI3dY=,iv:7ztpZquVBNZFt59OcNM2IXiDdmMjE8AGs1lTDZzeNWs=,tag:xpak7lbN6hrXaSKoWSbHYQ==,type:str]
version: 3.13.2