--- # Was a plain ConfigMap with client_secret hardcoded in plaintext - found # and fixed 2026-08-20. Unlike argocd/nextcloud, Vault had NO copy of # this at all - the only places it existed were here AND in # infrastructure/grafana/manifests/grafana-oauth-secret.yaml (also fixed # alongside this, same Vault path). Created secret/grafana-oauth with the # existing live value (not rotated - changing it would break login until # both sides are updated together). apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: authentik-blueprints-grafana namespace: authentik spec: refreshInterval: 1h secretStoreRef: kind: ClusterSecretStore name: vault-backend target: name: authentik-blueprints-grafana creationPolicy: Owner template: metadata: labels: goauthentik.io/blueprint: "true" data: grafana.yaml: |- version: 1 metadata: name: grafana-oidc entries: # ============================================================================ # AUTO-CREATE GRAFANA GROUPS # ============================================================================ # These groups control access levels in Grafana via OAuth role mapping: # - Grafana Admins → Admin role (full access) # - Grafana Editors → Editor role (can edit dashboards) # - Grafana Viewers → Viewer role (read-only) # # AUTOMATIC ADMIN ACCESS: # - Anyone in "authentik Admins" automatically gets Grafana Admin access # - No manual configuration needed! # ============================================================================ - model: authentik_core.group id: grafana-admins-group state: present identifiers: name: Grafana Admins attrs: name: Grafana Admins is_superuser: false # Note: authentik Admins are automatically granted access via role_attribute_path # in Grafana configuration (see grafana/values.yaml) - model: authentik_core.group id: grafana-editors-group state: present identifiers: name: Grafana Editors attrs: name: Grafana Editors is_superuser: false - model: authentik_core.group id: grafana-viewers-group state: present identifiers: name: Grafana Viewers attrs: name: Grafana Viewers is_superuser: false # ============================================================================ # GRAFANA OAUTH2 PROVIDER # ============================================================================ - model: authentik_providers_oauth2.oauth2provider id: grafana-provider state: present identifiers: name: Grafana attrs: name: Grafana client_id: bd03e9139dd2063c6c44c4d2f65f51d69de3ba0b6d6b1b9b41c255d2376d2dcc client_secret: "{{ .clientSecret }}" authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] authentication_flow: !Find [authentik_flows.flow, [slug, default-authentication-flow]] invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]] redirect_uris: - url: "https://grafana.kube.huskypup.net/login/generic_oauth" matching_mode: strict property_mappings: - !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]] client_type: confidential access_code_validity: "minutes=10" access_token_validity: "hours=1" refresh_token_validity: "days=30" signing_key: !Find [authentik_crypto.certificatekeypair, [name, default]] # ============================================================================ # GRAFANA APPLICATION # ============================================================================ - model: authentik_core.application id: grafana-application state: present identifiers: slug: grafana attrs: name: Grafana slug: grafana policy_engine_mode: any provider: !KeyOf grafana-provider data: - secretKey: clientSecret remoteRef: key: grafana-oauth property: client-secret