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 <flokli@flokli.de>
Reviewed-by: Jonas Chevalier <zimbatm@zimbatm.com>
This commit is contained in:
Florian Klink 2025-05-05 00:34:23 +03:00 committed by clbot
parent 018f3b38a6
commit e20ff4cb60
7 changed files with 144 additions and 144 deletions

31
ops/keycloak/buildkite.tf Normal file
View file

@ -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"
# }

View file

@ -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"
# }

27
ops/keycloak/forgejo.tf Normal file
View file

@ -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" {
# }

26
ops/keycloak/gerrit.tf Normal file
View file

@ -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" {
# }

58
ops/keycloak/grafana.tf Normal file
View file

@ -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",
]
}

View file

@ -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" {
# }