Skip to content

Per-user permission levels (admin / read-only / no-export) via the SSO proxy #116

Description

@delabrcd

Problem

The app has no app-level auth by design — it trusts the reverse-proxy / SSO (Authentik forward-auth) gate, and everyone who gets through has full control: they can manage NG-login credentials, trigger scrapes, change settings, and export all data. Long-term we want differentiated access: e.g. an admin (full control), a read-only viewer (can see charts/bills but not mutate or manage credentials), and an even more restricted viewer without data export (no CSV / no bulk-PDF zip). This must not violate the "no public app-login" principle.

Proposal (long-term — design first)

Do not build an in-app login. Instead derive identity + role from the trusted SSO proxy headers the Authentik forward-auth outpost already injects (e.g. X-authentik-username, X-authentik-groups), and map groups → roles:

  • admin — full control (current behavior).
  • viewer — read dashboards/bills; blocked from mutations (NG-login add/remove, settings writes, manual scrape trigger).
  • viewer-no-exportviewer minus CSV export and bulk-PDF download.

Enforce server-side in the API routes (never just hide buttons): a small requireRole() helper reads the forwarded header, resolves the role, and gates the relevant routes; the UI also hides controls the role can't use. Headers must only be trusted from the proxy (the app stays non-public per AGENTS.md). Role→group mapping is config (env or AppSetting), with a safe default (no header / unknown ⇒ treat as admin only when the app is in its current single-user mode, configurable — decide in design).

Acceptance criteria

  • A documented role model + a pure roleFromRequest(headers, config) with unit tests (header parsing, default/unknown handling).
  • Mutating routes (NG-login mgmt, /api/settings writes, /api/refresh) and export routes (CSV, bulk-PDF) reject below-threshold roles server-side (tested), not just hidden in the UI.
  • No public app-login introduced; financial data never served un-gated; behavior is unchanged for a single-admin install (back-compat default).
  • Security review of the header-trust path before ship.

Pointers

  • SSO gate / forwarded headers: compose/authentik/terraform (forward-auth provider) and SWAG authentik-location.conf (server-side, infra repo).
  • Export routes (CSV / bulk-PDF zip) and /api/refresh, /api/settings, NG-login routes under app/src/app/api/*.
  • AGENTS.md rules CSV export / download #3 (secrets) and Weather-normalized usage (heating/cooling degree-days) #5 (no public app-auth) are binding constraints here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:dataData model, accuracy, exportarea:opsDeploy / backup / operationsenhancementNew feature or requestpriority:lowSomeday: speculative, heavy, optional, or long-term

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions