Files
serverAppConfigs/serverAppConfigs-docs/Infrastructure/Grafana.md
T
Frank 9d678122d7 docs: grafana OAuth2-RP contract + authentik fork quirks (live-verified 2026-08-31)
Token exchange chain verified end-to-end in-process on the live provider
(pk 9): authorize -> ORM-minted code -> form-encoded token exchange with
Basic client auth -> userinfo. Key findings documented:
- Application row + grant_types must exist before authorize can complete
- token endpoint consumes form-encoded bodies only (JSON body => no
  grant_type parsed -> unsupported_grant_type); client auth is Basic-only
- PropertyMappingEvaluator.evaluate(*args,**kwargs) forwards kwargs to
  BaseEvaluator.evaluate(expression_source), so context kwargs become the
  expression source and every evaluation raises a swallowed exception;
  userinfo therefore answers sub-only claims for every provider in this
  fork. Scope granting filter (provider= M2M descriptor) is always empty.
- Grafana identity = sub hash until the evaluator bug is fixed upstream.
2026-08-31 06:06:57 -07:00

2.3 KiB

Grafana

Grafana visualizes the metrics that Prometheus collects from every service. It runs on Dankclaw and is reachable at grafana.franksdank.cloud (via Caddy, behind the Anubis challenge + embedded-outpost gate; login happens inside Grafana via the Authentik OAuth2 button).

Host: Dankclaw — Hostname: grafana.franksdank.cloud — Port: 3002 (internal) — Docs: https://grafana.com/docs

Facts

Item Value
Image docker.io/grafana/grafana:latest
Port 3002 (host) → 3000 (container)
Data volume dashboards, users, datasource config
Datasource Prometheus (on the same host)
Provisioning dashboards in /etc/grafana/provisioning/dashboards

Configuration

environment:
  GF_SECURITY_ADMIN_USER: "${GRAFANA_ADMIN_USER}"
  GF_SECURITY_ADMIN_PASSWORD: "${GRAFANA_ADMIN_PASSWORD}"
  GF_SERVER_ROOT_URL: "https://grafana.franksdank.cloud"
volumes:
  - /opt/grafana/data:/var/lib/grafana
  - /opt/grafana/provisioning:/etc/grafana/provisioning:ro

Datasource

Point Grafana at the Prometheus service by name (http://prometheus:9090) on the shared podman network.

Healthcheck

Grafana responds on /api/health with 200 and "database":"ok".

Gotchas

  • Change the default admin credentials at first boot (env or UI).
  • Dashboards provisioned as YAML survive container recreation; UI-created ones live in the data volume — back it up.
  • Auth = OAuth2 relying-party, not auth_proxy. The embedded outpost carries no provider token (token=None), so no identity header ever reaches Grafana; RP mode is topology-independent. The full verified contract (provider pk 9, client_id grafana-21ca190cde75d60f, global authorize/token/userinfo paths, Basic client auth, form-encoded token body, and the fork's userinfo-claims bug that leaves identity at the sub hash only) is in Authentik → "OAuth2 relying-party quirks". Consequences for Grafana: users auto-upsert as Viewer with login = <sub hex>; no email/groups/role claims reach Grafana until the evaluator bug is fixed — do not write role mappings that depend on those claims. The local admin account stays the only Admin.

See Also