Frontière multi-tenant
L'invariant de sécurité principal : chaque requête PromQL passe par `composeQuery` ou `rewritePromQL`. Les deux injectent organization_id comme mandatory label matcher. Il n'existe pas de raw-query path pour l'input utilisateur.
composeQuery
Prend un bare metric name + filters → construit du PromQL de la forme :
metric{organization_id="<org-id>", host="web-01"}Les mandatory filters l'emportent toujours. Les optionnels (des URL params) sont ajoutés s'ils n'entrent pas en conflit.
rewritePromQL
Parse le PromQL de l'utilisateur via prometheus/promql/parser, parcourt l'AST via parser.Inspect. Sur chaque VectorSelector et MatrixSelector, les LabelMatchers sont remplacés par un merged set où organization_id l'emporte.
Un utilisateur ne peut pas « contourner » organization_id même en l'indiquant explicitement dans la requête — le rewrite l'écrase.