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.
58 lines
2.3 KiB
Markdown
58 lines
2.3 KiB
Markdown
# 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
|
|
|
|
```yaml
|
|
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
|
|
|
|
- [[Dankclaw Stack]]
|
|
- [[Prometheus]] — the datasource
|
|
- [[Observability]] — the whole stack
|