tracksolid_timescale_grafan.../migrations/18_grant_reporting_ro.sql
david kiania 8ddbd7b745 feat(db): grant grafana_ro read access to reporting.* (Phase 0 role)
migrations/18_grant_reporting_ro.sql — grants USAGE + SELECT on the reporting.*
layer to grafana_ro, with DEFAULT PRIVILEGES so future reporting views are
auto-readable. grafana_ro is the read-only role the staging dashboard_api
connects as; it read tracksolid.* but never reporting.* (the prod dashboard_api
uses the app role), surfacing as "permission denied for view v_filter_drivers /
v_daily_summary" on the staging /analytics/* endpoints. Read-only only — no
write/REFRESH. Registered 18 in run_migrations.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:24:55 +03:00

24 lines
1.3 KiB
SQL

-- 18_grant_reporting_ro.sql
-- Read-only access to the reporting.* layer for grafana_ro.
--
-- grafana_ro is the read-only role the STAGING dashboard_api connects as (it reads
-- the prod DB but must be physically unable to write — see
-- docs/STAGING_FLEETOPS_ARCHITECTURE.md §6). It already reads tracksolid.* (Grafana
-- + the migration-07 analytics views), but was never granted SELECT on the
-- reporting.* map/analytics layer (migration 11) — the prod dashboard_api connects
-- as the app/superuser role, so the gap went unnoticed until the read-only staging
-- instance hit "permission denied for view v_filter_drivers / v_daily_summary".
--
-- This grants USAGE + SELECT across reporting.* and sets DEFAULT PRIVILEGES so any
-- future reporting view/table is auto-readable by grafana_ro (no re-grant needed).
-- Read-only only: no INSERT/UPDATE/DELETE, so grafana_ro still cannot write or
-- REFRESH. Guarded + idempotent -> safe to re-apply.
DO $grants$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'grafana_ro') THEN
GRANT USAGE ON SCHEMA reporting TO grafana_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA reporting TO grafana_ro; -- includes views
ALTER DEFAULT PRIVILEGES IN SCHEMA reporting GRANT SELECT ON TABLES TO grafana_ro;
END IF;
END $grants$;