Repository navigation
feat(queryapi): serve metric queries with server-enforced project isolation - #208
Merged
Merged
Conversation
--logs-storage names the log backend now that a metric backend is coming. --storage stays for one release as a deprecated alias, and startup fails if both are set to different values. The deployment keeps the STORAGE env var, so overlays need no edit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MetricStore is the Prometheus query API counterpart to LogStore. Each method returns the backend's data payload unchanged and must refuse a context with no project before contacting the backend. The fake answers every query with one series for the caller's project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prometheus clients send fractional Unix seconds and steps as bare seconds, which the Loki parser misreads. Timestamps parse exactly to the nanosecond without a float. Durations must be positive, so a step that rounds to zero or overflows is rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The five metric routes stop returning 501. Handlers validate Prometheus API parameters, bound query_range by --max-range and 11,000 points per series, pass the backend's data through unchanged, and map failures to the Prometheus error envelope. /readyz gains a metrics storage check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The store builds every backend request from typed fields and adds extra_label=<project label>=<project>, taking the project only from the verified identity. Client parameters are never copied, so a caller cannot add or replace the tenancy filter. extra_label is a VictoriaMetrics extension that other servers ignore, so tenancy is an explicit mode rather than implied by the backend URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--metrics-storage=prometheus needs --prometheus-url and --prometheus-tenancy=extra-label. The tenancy flag has no default, so isolation is never enabled or lost by accident; startup fails without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seeds two projects into a real VictoriaMetrics and asserts that each endpoint returns none of the other project's series, labels or values, pairing every negative check with a positive one. With extra_label removed, every endpoint's check fails. The task fails unless the test reports a pass, so a skipped or renamed test cannot pass silently, and CI runs it on every pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VictoriaMetrics returns a query timeout as HTTP 422 with a numeric errorType, so it surfaced as a 400 bad_data. Timeout-shaped errors on 422 or 503 now map to 503 timeout. The integration test now runs with the result cache on and checks that one project's cached results never reach another. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Store and Metrics read as different kinds of thing. Fields, test helpers and the fake stores now say LogStore and MetricStore, and the logs readiness check is logs-storage to match metrics-storage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ecv
approved these changes
Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #207.
queryapi now serves its five Prometheus-shaped metric routes instead of returning 501. Every metric query is confined to the caller's project by the server, with the project taken only from the verified identity, the same rule the logs path follows.
How tenancy is enforced
storage.MetricStoresits alongsideLogStore. Theprometheusbackend is a narrownet/httpclient for any Prometheus-query-API server, not a reverse proxy.extra_label=<project label>=<project>. Client parameters are never copied, so a caller can't add, replace, or remove the filter. A request with no project sends nothing.extra_labelis a VictoriaMetrics extension, and servers that don't implement it ignore it. So tenancy is an explicit, required flag (--prometheus-tenancy=extra-label) rather than something implied by the backend URL. Startup fails without it.Proof it refuses
task test-integration-prometheusseeds two projects into VictoriaMetrics v1.114.0 and, as one project, checksquery,query_range,series,labels, andlabel/{name}/values, with the result cache on. Every negative check is paired with a positive one.With the
extra_labelline removed, every endpoint's isolation check fails (the other project's series, labels, and values come back, andsumreturns both projects' total). With it restored, all pass. The task fails unless the test reports a pass, so a skipped or renamed test can't go green. CI runs it asTest (queryapi integration-prometheus).Other changes
--max-range, the 11,000-point limit, atimeoutcapped at--query-timeout, and the Prometheus error envelope. Backend failures are logged, not returned.errorType; they now surface as 503timeout./readyzgainsmetrics-storage. The logs check is renamedstorage→logs-storageto match, which changes/readyz?verboseoutput.--logs-storagereplaces--storage, which stays as a deprecated alias for one release. The deployment keeps theSTORAGEenv var, so overlays need no edit.--metrics-storage(defaultfake),--prometheus-url,--prometheus-tenancy,--prometheus-project-label,--max-range,--max-response-bytes.Rollout
Merging changes nothing in-cluster:
--metrics-storagedefaults tofake. Pointing queryapi at VictoriaMetrics, moving cloud-portal over, and closing the direct path to VictoriaMetrics happen in infra and cloud-portal.Follow-ups
bad_data.🤖 Generated with Claude Code