Multi-Tenancy-Grenze
Das zentrale Security-Invariant: jede PromQL-Query läuft durch `composeQuery` oder `rewritePromQL`. Beide injizieren organization_id als mandatory label matcher. Es gibt keinen Raw-Query-Pfad für User-Input.
composeQuery
Nimmt einen bare metric name + filters → baut PromQL der Form:
metric{organization_id="<org-id>", host="web-01"}Mandatory filters gewinnen immer. Optionale (aus URL-Params) werden hinzugefügt, wenn sie nicht kollidieren.
rewritePromQL
Parst das User-PromQL über prometheus/promql/parser, durchläuft den AST über parser.Inspect. An jedem VectorSelector und MatrixSelector werden die LabelMatchers durch ein Merged-Set ersetzt, in dem organization_id gewinnt.
Ein Nutzer kann organization_id auch durch explizite Angabe in der Query nicht „umgehen" — das Rewrite überschreibt es.