diff --git a/infrastructure/terraform/authentik/app-grafana.tf b/infrastructure/terraform/authentik/app-grafana.tf new file mode 100644 index 0000000000..67598cffa2 --- /dev/null +++ b/infrastructure/terraform/authentik/app-grafana.tf @@ -0,0 +1,60 @@ +module "onepassword_grafana" { + source = "github.com/bjw-s/terraform-1password-item?ref=main" + vault = "Kubernetes" + item = "grafana" +} + +resource "authentik_provider_oauth2" "grafana" { + name = "Grafana" + + client_id = module.onepassword_grafana.fields.AUTHENTIK_CLIENT_ID + client_secret = module.onepassword_grafana.fields.AUTHENTIK_CLIENT_SECRET + + authorization_flow = data.authentik_flow.default-provider-authorization-implicit-consent.id + + redirect_uris = [module.onepassword_grafana.fields.AUTHENTIK_GRAFANA_URL] + + property_mappings = [ + data.authentik_scope_mapping.scope-email.id, + data.authentik_scope_mapping.scope-profile.id, + data.authentik_scope_mapping.scope-openid.id, + ] +} + +resource "authentik_application" "grafana" { + name = "Grafana" + slug = "grafana" + protocol_provider = authentik_provider_oauth2.grafana.id + + meta_launch_url = module.onepassword_grafana.fields.AUTHENTIK_GRAFANA_URL +} + +resource "authentik_group" "grafana_admins" { + name = "Grafana Admins" +} + +resource "authentik_group" "grafana_editors" { + name = "Grafana Editors" +} + +resource "authentik_group" "grafana_viewers" { + name = "Grafana Viewers" +} + +resource "authentik_policy_binding" "grafana-access-admin" { + target = authentik_application.grafana.uuid + group = authentik_group.grafana_admins.id + order = 0 +} + +resource "authentik_policy_binding" "grafana-access-editors" { + target = authentik_application.grafana.uuid + group = authentik_group.grafana_editors.id + order = 0 +} + +resource "authentik_policy_binding" "grafana-access-viewers" { + target = authentik_application.grafana.uuid + group = authentik_group.grafana_viewers.id + order = 0 +} diff --git a/infrastructure/terraform/authentik/directory.tf b/infrastructure/terraform/authentik/directory.tf index 35e2c09f41..9cfa62b2fc 100644 --- a/infrastructure/terraform/authentik/directory.tf +++ b/infrastructure/terraform/authentik/directory.tf @@ -12,5 +12,9 @@ resource "authentik_user" "scotte" { name = module.onepassword_scotte.fields.FULLNAME email = module.onepassword_scotte.fields.EMAIL password = module.onepassword_scotte.fields.password - groups = [data.authentik_group.admins.id, authentik_group.users.id] + groups = [ + data.authentik_group.admins.id, + authentik_group.users.id, + authentik_group.grafana_admins.id + ] } diff --git a/infrastructure/terraform/authentik/flows.tf b/infrastructure/terraform/authentik/flows.tf index 4327dab024..ec4a727d5a 100644 --- a/infrastructure/terraform/authentik/flows.tf +++ b/infrastructure/terraform/authentik/flows.tf @@ -152,3 +152,7 @@ data "authentik_flow" "default-source-authentication" { data "authentik_flow" "default-source-enrollment" { slug = "default-source-enrollment" } + +data "authentik_flow" "default-provider-authorization-implicit-consent" { + slug = "default-provider-authorization-implicit-consent" +} diff --git a/infrastructure/terraform/authentik/mappings.tf b/infrastructure/terraform/authentik/mappings.tf index 8e985f5283..86f6432542 100644 --- a/infrastructure/terraform/authentik/mappings.tf +++ b/infrastructure/terraform/authentik/mappings.tf @@ -29,3 +29,15 @@ data "authentik_property_mapping_saml" "username" { data "authentik_property_mapping_saml" "email" { managed = "goauthentik.io/providers/saml/email" } + +data "authentik_scope_mapping" "scope-email" { + name = "authentik default OAuth Mapping: OpenID 'email'" +} + +data "authentik_scope_mapping" "scope-profile" { + name = "authentik default OAuth Mapping: OpenID 'profile'" +} + +data "authentik_scope_mapping" "scope-openid" { + name = "authentik default OAuth Mapping: OpenID 'openid'" +} diff --git a/kubernetes/main/apps/monitoring/grafana/app/grafana-secrets.yaml b/kubernetes/main/apps/monitoring/grafana/app/grafana-secrets.yaml index c6200a3f07..b29d91632f 100644 --- a/kubernetes/main/apps/monitoring/grafana/app/grafana-secrets.yaml +++ b/kubernetes/main/apps/monitoring/grafana/app/grafana-secrets.yaml @@ -18,7 +18,14 @@ spec: data: adminUser: "{{ .ADMIN_USER }}" adminPassword: "{{ .ADMIN_PASSWORD }}" - GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: "{{ .GRAFANA_OAUTH_CLIENT_SECRET }}" + + # Authelia + # GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: "{{ .GRAFANA_OAUTH_CLIENT_SECRET }}" + + # Authentik + GF_AUTH_GENERIC_OAUTH_CLIENT_ID: "{{ .AUTHENTIK_CLIENT_ID }}" + GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: "{{ .AUTHENTIK_CLIENT_SECRET }}" + # Database configuration GF_DATABASE_USER: &dbuser grafana GF_DATABASE_PASSWORD: &dbpass "{{ .GRAFANA_DATABASE_PASSWORD }}" diff --git a/kubernetes/main/apps/monitoring/grafana/app/helm-release.yaml b/kubernetes/main/apps/monitoring/grafana/app/helm-release.yaml index 006c34b0a4..08d9b52a18 100644 --- a/kubernetes/main/apps/monitoring/grafana/app/helm-release.yaml +++ b/kubernetes/main/apps/monitoring/grafana/app/helm-release.yaml @@ -50,39 +50,57 @@ spec: userKey: adminUser passwordKey: adminPassword env: - GF_AUTH_GENERIC_OAUTH_API_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/userinfo - GF_AUTH_GENERIC_OAUTH_AUTH_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/authorization - GF_AUTH_GENERIC_OAUTH_TOKEN_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/token + # Authelia + # GF_AUTH_GENERIC_OAUTH_API_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/userinfo + # GF_AUTH_GENERIC_OAUTH_AUTH_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/authorization + # GF_AUTH_GENERIC_OAUTH_TOKEN_URL: https://auth.${SECRET_DOMAIN_NAME}/api/oidc/token + GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: natel-discrete-panel,pr0ps-trackmap-panel,panodata-map-panel GF_SECURITY_ANGULAR_SUPPORT_ENABLED: true envFromSecrets: - name: grafana-secret grafana.ini: - # default: - # force_migration: true auth: - # signout_redirect_url: https://auth.${SECRET_DOMAIN_NAME}/logout - oauth_auto_login: true - oauth_allow_insecure_email_lookup: true + signout_redirect_url: https://sso.${SECRET_DOMAIN_NAME}/application/o/grafana/end-session/ + oauth_auto_login: true auth.generic_oauth: - enabled: true - name: Authelia - icon: signin - client_id: grafana - scopes: "openid profile email groups" - empty_scopes: false - login_attribute_path: preferred_username - groups_attribute_path: groups - name_attribute_path: name - use_pkce: true - auth.generic_oauth.group_mapping: - role_attribute_path: | - contains(groups[*], 'admins') && 'Admin' || contains(groups[*], 'people') && 'Viewer' - org_id: 1 + name: authentik + enabled: true + scopes: "openid profile email" + auth_url: "https://sso.${SECRET_DOMAIN_NAME}/application/o/authorize/" + token_url: "https://sso.${SECRET_DOMAIN_NAME}/application/o/token/" + api_url: "https://sso.${SECRET_DOMAIN_NAME}/application/o/userinfo/" + # Optionally map user groups to Grafana roles + role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer' + users: + auto_assign_org = true + auto_assign_org_id = 1 + # Authelia + # # default: + # # force_migration: true + # auth: + # # signout_redirect_url: https://auth.${SECRET_DOMAIN_NAME}/logout + # oauth_auto_login: true + # oauth_allow_insecure_email_lookup: true + # auth.generic_oauth: + # enabled: true + # name: Authelia + # icon: signin + # client_id: grafana + # scopes: "openid profile email groups" + # empty_scopes: false + # login_attribute_path: preferred_username + # groups_attribute_path: groups + # name_attribute_path: name + # use_pkce: true + # auth.generic_oauth.group_mapping: + # role_attribute_path: | + # contains(groups[*], 'admins') && 'Admin' || contains(groups[*], 'people') && 'Viewer' + # org_id: 1 auth.basic: enabled: false auth.anonymous: - enabled: true + enabled: false org_id: 1 org_role: Viewer date_formats: