Task · GCV-0017

Add a datasource access API that aggregates LBAC rules per datasource

Description

Add a platform-owned composite, one per datasource, owning the datasource, its permission items, and the single aggregated LBAC rules resource.

The design constraint is a shape mismatch, not a provider defect. DataSourceConfigLBACRules is one resource per datasource whose rules field is a JSON-encoded map keyed by team UID, and its provider documentation states it manages the entire LBAC rules tree and overwrites existing rules. The natural consumer-facing shape is per-team, so if the API exposes a per-team claim, several claims map onto one whole-tree resource and the last writer wins. The function must therefore fold every team claim into one resource, and admission must reject a second composite targeting the same datasource. This is the same pattern the existing content-access API already uses for folder and dashboard ACLs, extended to the one place where the resource looks per-team and is not.

Two security facts make this more than plumbing. LBAC is opt-in per team: a team with no rules on a datasource can query all of it, so omitting rules is an allow-all default rather than a deny. And LBAC is bypassed by anyone holding broader datasource query permission, so Grafana guidance is to strip default Viewer and Editor query access first. An API exposing LBAC without owning the datasource permissions ships a false sense of isolation.

Other verified constraints: LBAC applies only to datasources using basic auth; it requires Grafana 11.5.0 or later and an Enterprise or Cloud entitlement; prefer the permission item form over the whole-set permission form for everything else. Private networking is one field, private_data_source_connect_network_id, top-level on the datasource and Cloud-only, but the network and its token are Cloud-plane objects while the binding is stack-plane, so that combination needs two ProviderConfigs.

Keep endpoints and credentials out of this repository. Datasource connection details are environment-owned.

Acceptance Criteria

Definition of Done

Implementation Plan

Wave 2: implement and security-validate one-owner datasource access with aggregated LBAC and permission items; root wires and gates.

Wave 2 correction: use one authoritative whole-set DataSourcePermission because item resources cannot continuously enforce absent broad grants.

Implementation Notes

Wave 1 lane F disposition, 2026-09-08: Not started and Parked because the mandatory root pre-fan-out pass did not produce a pushed seam SHA after route metadata was unavailable. Resume after GCV-0032 completes the section 5.0 pass, then spawn SECURITY on gpt-5.6-sol at high effort with fork_turns none and the pushed pre-pass SHA. No acceptance criterion or Definition of Done item was checked.

Wave 2 contract correction: DataSourcePermissionItem can delete its own grant only when that managed object is removed and cannot continuously enforce the absence of broad grants. The function therefore owns one authoritative whole-set DataSourcePermission plus one aggregated LBAC resource. The fourth acceptance criterion now records that enforceable contract.

Wave 2 verification: focused SECURITY race tests proved single ownership, complete LBAC aggregation, broad managed-grant removal, basic-auth refusal, and no embedded connection data. Catalog, integrated local gate, and hosted Validate run 34233686654 passed.

Final Summary

Delivered one-owner datasource access with one authoritative permission set and one aggregated per-datasource LBAC tree. Completing SHA 83f81afee7526fd6e7c4ec0a47675774d00036b8; hosted Validate run 34233686654 succeeded.

View the source file on GitHub