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).
82 lines
3.5 KiB
YAML
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 }}
|