diff --git a/argocd/manifests/databases/blumeops-pg.yaml b/argocd/manifests/databases/blumeops-pg.yaml index ea68c9b..8f1b878 100644 --- a/argocd/manifests/databases/blumeops-pg.yaml +++ b/argocd/manifests/databases/blumeops-pg.yaml @@ -45,14 +45,15 @@ spec: passwordSecret: name: blumeops-pg-borgmatic # teslamate user for TeslaMate Tesla data logger - # Note: superuser required for extension management during migrations + # Superuser removed. Extension ownership (cube, earthdistance) + # transferred manually so teslamate can ALTER EXTENSION UPDATE. + # earthdistance is untrusted — DROP+CREATE needs temporary + # superuser escalation during upgrades. - name: teslamate login: true - superuser: true connectionLimit: -1 ensure: present inherit: true - createdb: true passwordSecret: name: blumeops-pg-teslamate # authentik user for Authentik identity provider (runs on ringtail) diff --git a/docs/reference/services/postgresql.md b/docs/reference/services/postgresql.md index 4cccf4e..ef86418 100644 --- a/docs/reference/services/postgresql.md +++ b/docs/reference/services/postgresql.md @@ -38,7 +38,7 @@ The `immich-pg` cluster uses a custom image (`cloudnative-vectorchord`) with vec |------|---------|------|---------| | postgres | both | superuser | CNPG internal | | miniflux | blumeops-pg | app owner | Owns miniflux database | -| teslamate | blumeops-pg | superuser | TeslaMate (needs extensions) | +| teslamate | blumeops-pg | db owner | TeslaMate (owns extensions) | | authentik | blumeops-pg | createdb | [[authentik]] identity provider | | eblume | blumeops-pg | superuser | Admin access | | borgmatic | both | pg_read_all_data | [[borgmatic|Backup]] access | diff --git a/docs/reference/services/teslamate.md b/docs/reference/services/teslamate.md index f02e979..a11ed0e 100644 --- a/docs/reference/services/teslamate.md +++ b/docs/reference/services/teslamate.md @@ -1,6 +1,6 @@ --- title: TeslaMate -modified: 2026-03-23 +modified: 2026-04-07 last-reviewed: 2026-03-23 tags: - service @@ -39,7 +39,19 @@ Self-hosted Tesla data logger collecting vehicle telemetry from the Tesla API. - Drive Stats, Charging Stats, Projected Range - Timeline, Updates, Visited -Dashboards use PostgreSQL datasource (not Prometheus). +Dashboards use PostgreSQL datasource (not Prometheus). The Grafana datasource connects as the `teslamate` database user. + +## Database Permissions + +The `teslamate` role was initially provisioned as superuser to allow extension creation (`cube`, `earthdistance`) during initial setup. Superuser has been removed — `teslamate` is now a plain database owner with extension ownership transferred so it can `ALTER EXTENSION ... UPDATE` without superuser. + +Note: `earthdistance` is not a trusted extension in PostgreSQL, so `CREATE EXTENSION earthdistance` still requires superuser. If a future TeslaMate migration does `DROP EXTENSION ... CASCADE` + re-create (as happened in the 2024 migration), it will fail. In that case, temporarily grant superuser for the migration and remove it afterward. + +Extension ownership persists across pod restarts and CNPG failovers, but a full cluster rebuild (major PG upgrade, fresh `initdb`) would re-create extensions as `postgres`. After any rebuild, transfer ownership back: + +```sql +UPDATE pg_extension SET extowner = (SELECT oid FROM pg_roles WHERE rolname = 'teslamate') WHERE extname IN ('cube', 'earthdistance'); +``` ## Authentication