Files
cairnobs/deploy/helm/sentry/templates/secrets.yaml
T
jcoffey-dev 3eb0f4c589 Phase 4: SSO scaffolding, RBAC enforcement, tenant-scoped dashboards, audit logging, K8s deployment
RBAC (api/internal/authz) is live on /query and /dashboards, backed by a
new enterprise/ module (session issuance, audit logging, RBAC storage,
OIDC/SAML protocol wiring) that core never imports -- only calls over
HTTP. Found and fixed a real cross-tenant vulnerability in dashboards
(no tenant_id filtering at all) while writing the threat model doc.

Two things are explicitly NOT done, documented rather than hidden:
tenant isolation for log data itself (/query still shares one ClickHouse
connection and Tantivy index across every tenant -- RBAC controls who
can query, not what a query can see), and human SSO login (protocol
wiring exists, no HTTP handler calls it yet). See
docs/security/threat-model.md and docs/phase-4-runbook.md.

Also adds deploy/ (Go Operator + Helm chart, validated offline only --
no cluster was reachable in this environment).
2026-08-13 22:16:59 -07:00

82 lines
3.5 KiB
YAML

{{/*
Shared control-plane secrets -- the cluster-wide passwords
docker-compose.yml hardcodes as "sentry-dev-only"/etc (see its
clickhouse/metadata-postgres/metadata-migrate comments) become real
generated-or-supplied Secrets here. Each follows the same pattern: a
values override wins if set, otherwise a value is generated once and
kept stable across `helm upgrade` via `lookup` (so upgrades don't
silently rotate a live credential out from under a running Deployment --
same "never rotate a live credential without coordinating the
consumer-side change" reasoning as
deploy/operator/internal/controller/tenant_controller.go's
reconcileSecret). `lookup` returns nothing under `helm template`
(no live cluster) -- expected; see deploy/README.md's verification
section for what that means for this file specifically.
*/}}
{{- define "sentry.stableSecretValue" -}}
{{- $ns := index . 0 -}}
{{- $name := index . 1 -}}
{{- $key := index . 2 -}}
{{- $override := index . 3 -}}
{{- $existing := lookup "v1" "Secret" $ns $name -}}
{{- if $override -}}
{{ $override }}
{{- else if $existing -}}
{{ index $existing.data $key | b64dec }}
{{- else -}}
{{ randAlphaNum 40 }}
{{- end -}}
{{- end -}}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-clickhouse
labels:
{{- include "sentry.labels" . | nindent 4 }}
type: Opaque
stringData:
# The official clickhouse-server image locks down *network* access
# entirely for the implicit `default` user unless this is genuinely
# non-empty -- see docker-compose.yml's clickhouse service comment.
# Not a substitute for task 2's per-tenant credentials (still unbuilt
# -- see deploy/operator's Tenant controller); this is the shared
# admin/migration credential only.
password: {{ include "sentry.stableSecretValue" (list .Release.Namespace (printf "%s-clickhouse" .Release.Name) "password" .Values.clickhouse.password) }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-postgres
labels:
{{- include "sentry.labels" . | nindent 4 }}
type: Opaque
stringData:
password: {{ include "sentry.stableSecretValue" (list .Release.Namespace (printf "%s-postgres" .Release.Name) "password" .Values.postgres.password) }}
# Restricted audit_writer Postgres role (Phase 4 task 4) -- INSERT+SELECT
# only, via its own pool, never the shared role above. See
# /docs/phase-4-isolation-design.md's audit-logging section and
# metadata/README.md.
auditWriterPassword: {{ include "sentry.stableSecretValue" (list .Release.Namespace (printf "%s-postgres" .Release.Name) "auditWriterPassword" .Values.postgres.auditWriterPassword) }}
{{- if .Values.enterprise.enabled }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-enterprise-auth
labels:
{{- include "sentry.labels" . | nindent 4 }}
type: Opaque
stringData:
# Must be >= 32 bytes -- see enterprise/internal/config.Load and
# enterprise/internal/session.MinSigningKeyBytes. Rotating this
# invalidates every outstanding session/service token -- same
# "don't rotate a live credential silently" reasoning as above,
# which is why it's kept stable via the lookup above rather than
# regenerated on every `helm upgrade`.
sessionSigningKey: {{ include "sentry.stableSecretValue" (list .Release.Namespace (printf "%s-enterprise-auth" .Release.Name) "sessionSigningKey" .Values.enterprise.sessionSigningKey) }}
{{- if .Values.enterprise.oidc.clientSecret }}
oidcClientSecret: {{ .Values.enterprise.oidc.clientSecret | quote }}
{{- end }}
{{- end }}