fix(platform): apply production hardening from audit plan

Close billing, tenancy, migration, build, and CI/CD gaps identified in the
audit: wallet/gateway guards, full-UUID namespaces, idempotent migrations with
base schema, stateful service stability, safer Dockerfiles/git builds, and
platform chart hardening (Redis auth, RollingUpdate, backups, Swagger off).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
keyhan
2026-07-02 19:35:07 +03:30
parent 34c110be6a
commit 22359be40e
55 changed files with 4883 additions and 381 deletions
@@ -9,8 +9,14 @@ metadata:
{{- include "cloudhost-platform.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.backend.replicas }}
# Zero-downtime rollouts: DB migrations run in a pre-upgrade hook Job, so the
# new pod only starts against a ready schema. The uploads PVC is RWO but
# local-path volumes pin pods to the same node, so surge pods can attach.
strategy:
type: Recreate
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: {{ include "cloudhost-platform.backend.fullname" . }}
@@ -72,6 +78,11 @@ spec:
value: {{ include "cloudhost-platform.redis.fullname" . }}
- name: REDIS_PORT
value: "6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "cloudhost-platform.secretName" . }}
key: redis-password
- name: JWT_SECRET
valueFrom:
secretKeyRef:
@@ -7,7 +7,9 @@ metadata:
labels:
{{- include "cloudhost-platform.labels" . | nindent 4 }}
annotations:
helm.sh/hook: post-install,post-upgrade
# Run BEFORE the backend rolls out so schema-dependent code never starts
# against an unmigrated database.
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-weight: "5"
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
@@ -47,9 +49,20 @@ spec:
- -c
- |
set -e
# Track applied migrations so each file runs exactly once — the
# loop is idempotent across every helm upgrade.
psql -v ON_ERROR_STOP=1 -c "CREATE TABLE IF NOT EXISTS schema_migrations (filename TEXT PRIMARY KEY, applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW());"
for f in $(ls /migrations/*.sql | sort); do
echo ">>> Applying $f"
psql -v ON_ERROR_STOP=1 -f "$f"
name=$(basename "$f")
applied=$(psql -tA -c "SELECT 1 FROM schema_migrations WHERE filename = '$name';")
if [ "$applied" = "1" ]; then
echo ">>> Skipping $name (already applied)"
continue
fi
echo ">>> Applying $name"
psql -v ON_ERROR_STOP=1 --single-transaction \
-f "$f" \
-c "INSERT INTO schema_migrations (filename) VALUES ('$name');"
done
echo ">>> All migrations applied"
volumeMounts:
@@ -41,6 +41,8 @@ spec:
FILE="/backup/cloudhost-${STAMP}.sql.gz"
pg_dump | gzip > "$FILE"
echo "Backup written to $FILE"
# Retention: keep the last {{ .Values.backups.postgres.retentionDays | default 7 }} days
find /backup -name 'cloudhost-*.sql.gz' -mtime +{{ .Values.backups.postgres.retentionDays | default 7 }} -delete
volumeMounts:
- name: backup
mountPath: /backup
@@ -19,6 +19,10 @@ spec:
labels:
app: {{ include "cloudhost-platform.postgres.fullname" . }}
spec:
{{- with .Values.postgres.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: postgres
image: {{ .Values.images.postgres | quote }}
@@ -19,9 +19,26 @@ spec:
labels:
app: {{ include "cloudhost-platform.redis.fullname" . }}
spec:
{{- with .Values.redis.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: redis
image: {{ .Values.images.redis | quote }}
args: ["--requirepass", "$(REDIS_PASSWORD)"]
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "cloudhost-platform.secretName" . }}
key: redis-password
# redis-cli reads REDISCLI_AUTH so authenticated probes need no -a flag
- name: REDISCLI_AUTH
valueFrom:
secretKeyRef:
name: {{ include "cloudhost-platform.secretName" . }}
key: redis-password
ports:
- containerPort: 6379
volumeMounts:
@@ -22,6 +22,10 @@ Secret out-of-band (e.g. SealedSecret in the gitops repo).
{{- if not $kubeconfigKey }}
{{- if and $existing (hasKey $existing.data "cluster-kubeconfig-key") }}{{- $kubeconfigKey = index $existing.data "cluster-kubeconfig-key" | b64dec }}{{- else }}{{- $kubeconfigKey = randAlphaNum 32 }}{{- end }}
{{- end }}
{{- $redisPass := .Values.redis.password }}
{{- if not $redisPass }}
{{- if and $existing (hasKey $existing.data "redis-password") }}{{- $redisPass = index $existing.data "redis-password" | b64dec }}{{- else }}{{- $redisPass = randAlphaNum 24 }}{{- end }}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
@@ -35,4 +39,5 @@ stringData:
jwt-secret: {{ $jwt | quote }}
jwt-refresh-secret: {{ $jwtRefresh | quote }}
cluster-kubeconfig-key: {{ $kubeconfigKey | quote }}
redis-password: {{ $redisPass | quote }}
{{- end }}