From e20ff4cb606fa95a6c7883c3f2b1a3c546ac3600 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Mon, 5 May 2025 00:34:23 +0300 Subject: [PATCH] fix(ops/keycloak): fix assigning grafana_roles keycloak_openid_user_client_role_protocol_mapper.grafana_role_mapper was missing. It is configured to make the client roles for this Application (and only those for this application) available in the grafana_roles claim. We can also disable full scope, as we're not interested in other role mappings. The Terraform files are a bit reorganized, everything configuring the Grafana client lives in grafana.tf (and vice-versa for Forgejo, Buildkite and Gerrit). The only thing left in permissions.tf is global groups, their memberships and mappings. Change-Id: I37b0755f4f8658518083353ec6cc0193e805d5c2 Reviewed-on: https://cl.snix.dev/c/snix/+/30476 Tested-by: besadii Autosubmit: Florian Klink Reviewed-by: Jonas Chevalier --- ops/keycloak/buildkite.tf | 31 +++++++++++ ops/keycloak/clients.tf | 105 ----------------------------------- ops/keycloak/forgejo.tf | 27 +++++++++ ops/keycloak/gerrit.tf | 26 +++++++++ ops/keycloak/grafana.tf | 58 +++++++++++++++++++ ops/keycloak/permissions.tf | 35 ------------ ops/modules/o11y/grafana.nix | 6 +- 7 files changed, 144 insertions(+), 144 deletions(-) create mode 100644 ops/keycloak/buildkite.tf delete mode 100644 ops/keycloak/clients.tf create mode 100644 ops/keycloak/forgejo.tf create mode 100644 ops/keycloak/gerrit.tf create mode 100644 ops/keycloak/grafana.tf diff --git a/ops/keycloak/buildkite.tf b/ops/keycloak/buildkite.tf new file mode 100644 index 000000000..e68330406 --- /dev/null +++ b/ops/keycloak/buildkite.tf @@ -0,0 +1,31 @@ +# resource "keycloak_saml_client" "buildkite" { +# realm_id = keycloak_realm.snix.id +# client_id = "https://buildkite.com" +# name = "Buildkite" +# base_url = "https://buildkite.com/sso/snix" + +# client_signature_required = false +# assertion_consumer_post_url = "https://buildkite.com/sso/~/1531aca5-f49c-4151-8832-a451e758af4c/saml/consume" + +# valid_redirect_uris = [ +# "https://buildkite.com/sso/~/1531aca5-f49c-4151-8832-a451e758af4c/saml/consume" +# ] +# } + +# resource "keycloak_saml_user_attribute_protocol_mapper" "buildkite_email" { +# realm_id = keycloak_realm.snix.id +# client_id = keycloak_saml_client.buildkite.id +# name = "buildkite-email-mapper" +# user_attribute = "email" +# saml_attribute_name = "email" +# saml_attribute_name_format = "Unspecified" +# } + +# resource "keycloak_saml_user_attribute_protocol_mapper" "buildkite_name" { +# realm_id = keycloak_realm.snix.id +# client_id = keycloak_saml_client.buildkite.id +# name = "buildkite-name-mapper" +# user_attribute = "displayName" +# saml_attribute_name = "name" +# saml_attribute_name_format = "Unspecified" +# } diff --git a/ops/keycloak/clients.tf b/ops/keycloak/clients.tf deleted file mode 100644 index 3b2f3c6f2..000000000 --- a/ops/keycloak/clients.tf +++ /dev/null @@ -1,105 +0,0 @@ -# All Keycloak clients, that is applications which authenticate -# through Keycloak. -# -# Includes first-party (i.e. snix-hosted) and third-party clients. - -resource "keycloak_openid_client" "grafana" { - realm_id = keycloak_realm.snix.id - client_id = "grafana" - name = "Grafana" - enabled = true - access_type = "CONFIDENTIAL" - standard_flow_enabled = true - base_url = "https://status.snix.dev" - full_scope_allowed = true - - valid_redirect_uris = [ - "https://status.snix.dev/*", - ] -} - -resource "keycloak_openid_client_default_scopes" "grafana_default_scopes" { - realm_id = keycloak_realm.snix.id - client_id = keycloak_openid_client.grafana.id - - default_scopes = [ - "profile", - "email", - "roles", - "web-origins", - ] -} - -resource "keycloak_openid_client" "gerrit" { - realm_id = keycloak_realm.snix.id - client_id = "gerrit" - name = "snix Gerrit" - enabled = true - access_type = "CONFIDENTIAL" - standard_flow_enabled = true - base_url = "https://cl.snix.dev" - description = "snix project's code review tool" - direct_access_grants_enabled = true - exclude_session_state_from_auth_response = false - - valid_redirect_uris = [ - "https://cl.snix.dev/*", - ] - - web_origins = [ - "https://cl.snix.dev", - ] -} - -resource "keycloak_openid_client" "forgejo" { - realm_id = keycloak_realm.snix.id - client_id = "forgejo" - name = "snix Forgejo" - enabled = true - access_type = "CONFIDENTIAL" - standard_flow_enabled = true - base_url = "https://git.snix.dev" - description = "snix project's code browsing, search and issue tracker" - direct_access_grants_enabled = true - exclude_session_state_from_auth_response = false - - valid_redirect_uris = [ - "https://git.snix.dev/*", - ] - - web_origins = [ - "https://git.snix.dev", - ] -} - -# resource "keycloak_saml_client" "buildkite" { -# realm_id = keycloak_realm.snix.id -# client_id = "https://buildkite.com" -# name = "Buildkite" -# base_url = "https://buildkite.com/sso/snix" - -# client_signature_required = false -# assertion_consumer_post_url = "https://buildkite.com/sso/~/1531aca5-f49c-4151-8832-a451e758af4c/saml/consume" - -# valid_redirect_uris = [ -# "https://buildkite.com/sso/~/1531aca5-f49c-4151-8832-a451e758af4c/saml/consume" -# ] -# } - -# resource "keycloak_saml_user_attribute_protocol_mapper" "buildkite_email" { -# realm_id = keycloak_realm.snix.id -# client_id = keycloak_saml_client.buildkite.id -# name = "buildkite-email-mapper" -# user_attribute = "email" -# saml_attribute_name = "email" -# saml_attribute_name_format = "Unspecified" -# } - -# resource "keycloak_saml_user_attribute_protocol_mapper" "buildkite_name" { -# realm_id = keycloak_realm.snix.id -# client_id = keycloak_saml_client.buildkite.id -# name = "buildkite-name-mapper" -# user_attribute = "displayName" -# saml_attribute_name = "name" -# saml_attribute_name_format = "Unspecified" -# } diff --git a/ops/keycloak/forgejo.tf b/ops/keycloak/forgejo.tf new file mode 100644 index 000000000..247aa4595 --- /dev/null +++ b/ops/keycloak/forgejo.tf @@ -0,0 +1,27 @@ +resource "keycloak_openid_client" "forgejo" { + realm_id = keycloak_realm.snix.id + client_id = "forgejo" + name = "snix Forgejo" + enabled = true + access_type = "CONFIDENTIAL" + standard_flow_enabled = true + base_url = "https://git.snix.dev" + + description = "snix project's code browsing, search and issue tracker" + direct_access_grants_enabled = true + exclude_session_state_from_auth_response = false + + valid_redirect_uris = [ + "https://git.snix.dev/*", + ] + + web_origins = [ + "https://git.snix.dev", + ] +} + +# resource "keycloak_role" "forgejo_admin" { +# } +# +# resource "keycloak_role" "forgejo_trusted_contributor" { +# } diff --git a/ops/keycloak/gerrit.tf b/ops/keycloak/gerrit.tf new file mode 100644 index 000000000..6a6433513 --- /dev/null +++ b/ops/keycloak/gerrit.tf @@ -0,0 +1,26 @@ +resource "keycloak_openid_client" "gerrit" { + realm_id = keycloak_realm.snix.id + client_id = "gerrit" + name = "snix Gerrit" + enabled = true + access_type = "CONFIDENTIAL" + standard_flow_enabled = true + base_url = "https://cl.snix.dev" + description = "snix project's code review tool" + direct_access_grants_enabled = true + exclude_session_state_from_auth_response = false + + valid_redirect_uris = [ + "https://cl.snix.dev/*", + ] + + web_origins = [ + "https://cl.snix.dev", + ] +} + +# resource "keycloak_role" "gerrit_admin" { +# } +# +# resource "keycloak_role" "gerrit_trusted_contributor" { +# } diff --git a/ops/keycloak/grafana.tf b/ops/keycloak/grafana.tf new file mode 100644 index 000000000..f87ad2745 --- /dev/null +++ b/ops/keycloak/grafana.tf @@ -0,0 +1,58 @@ +resource "keycloak_openid_client" "grafana" { + realm_id = keycloak_realm.snix.id + client_id = "grafana" + name = "Grafana" + enabled = true + access_type = "CONFIDENTIAL" + standard_flow_enabled = true + base_url = "https://status.snix.dev" + + // disable full scope, roles are assigned via keycloak_openid_user_client_role_protocol_mapper + full_scope_allowed = false + + valid_redirect_uris = [ + "https://status.snix.dev/*", + ] +} + +resource "keycloak_role" "grafana_editor" { + realm_id = keycloak_realm.snix.id + client_id = keycloak_openid_client.grafana.id + name = "Editor" + description = "Can edit things in Grafana" +} + +resource "keycloak_role" "grafana_admin" { + realm_id = keycloak_realm.snix.id + client_id = keycloak_openid_client.grafana.id + name = "Admin" + description = "Can admin things in Grafana" +} + +# Expose the above two roles at `grafana_roles` +resource "keycloak_openid_user_client_role_protocol_mapper" "grafana_role_mapper" { + realm_id = keycloak_realm.snix.id + client_id = keycloak_openid_client.grafana.id + name = "grafana_roles mapper" + + claim_name = "grafana_roles" + claim_value_type = "String" + add_to_id_token = true + add_to_access_token = true + multivalued = true + + # https://github.com/keycloak/terraform-provider-keycloak/issues/1016 + client_id_for_role_mappings = keycloak_openid_client.grafana.client_id +} + +# It seems this is necessary +resource "keycloak_openid_client_default_scopes" "grafana_default_scopes" { + realm_id = keycloak_realm.snix.id + client_id = keycloak_openid_client.grafana.id + + default_scopes = [ + "profile", + "email", + "roles", + ] +} diff --git a/ops/keycloak/permissions.tf b/ops/keycloak/permissions.tf index dbe020693..f32bb60a5 100644 --- a/ops/keycloak/permissions.tf +++ b/ops/keycloak/permissions.tf @@ -58,38 +58,3 @@ resource "keycloak_group_roles" "trusted_contributors_roles" { keycloak_role.grafana_editor.id ] } - -# Application-level roles. - -# Grafana - -resource "keycloak_role" "grafana_editor" { - realm_id = keycloak_realm.snix.id - client_id = keycloak_openid_client.grafana.id - name = "Editor" - description = "Can edit things in Grafana" -} - -resource "keycloak_role" "grafana_admin" { - realm_id = keycloak_realm.snix.id - client_id = keycloak_openid_client.grafana.id - name = "Admin" - description = "Can admin things in Grafana" -} - -# TODO: -# Forgejo - -# resource "keycloak_role" "forgejo_admin" { -# } -# -# resource "keycloak_role" "forgejo_trusted_contributor" { -# } -# -# # Gerrit -# -# resource "keycloak_role" "gerrit_admin" { -# } -# -# resource "keycloak_role" "gerrit_trusted_contributor" { -# } diff --git a/ops/modules/o11y/grafana.nix b/ops/modules/o11y/grafana.nix index 507213309..941f1098b 100644 --- a/ops/modules/o11y/grafana.nix +++ b/ops/modules/o11y/grafana.nix @@ -53,15 +53,13 @@ in "openid" "profile" "email" - "offline_access" - "roles" ]; allow_sign_up = true; auto_login = true; - allow_assign_grafana_admin = true; - role_attribute_path = "contains(grafana_roles[*], 'Admin') && 'GrafanaAdmin' || contains(grafana_roles[*], 'Editor') && 'Editor' || 'Viewer'"; + allow_assign_grafana_admin = true; + role_attribute_path = "contains(grafana_roles[*], 'Admin') && 'Admin' || contains(grafana_roles[*], 'Editor') && 'Editor' || 'Viewer'"; }; dashboards.default_home_dashboard_path = "${depot.ops.dashboards.node_exporter}";