# The groups claim — the single load-bearing decision of the migration. # # ZITADEL does not issue a `groups` claim. Authentik did, and these consumers # read it: kube-apiserver RBAC (`--oidc-groups-claim=groups` plus 11 RoleBindings # on oidc:), MinIO (`MINIO_IDENTITY_OPENID_CLAIM_NAME=groups`), Grafana # role mapping, and every service that filters on a group name. # # Plan §1.3 Option A keeps those consumers unchanged by synthesizing the claim. # Option B refactors all of them. This module takes responsibility only for the # ZITADEL side of Option A: the action resource and its trigger. # # The script body is NOT shipped by default. The go/no-go gate (§1.3, §1.5 task # 1.3) is: prove on the live instance that the action runtime can read project # roles plus user metadata and write both `groups` and the per-agent claims, # for a human token AND a machine-user token. Until that proof exists, enabling # this resource would move every consumer onto an unverified claim source: # # terraform apply -var enable_groups_claim_action=true \ # -var groups_claim_script=./groups-claim.js # # After it applies, verify with a real token exchange before moving a consumer: # # curl -s -X POST https://zitadel.riotpiao.com/oauth/v2/token \ # -d grant_type=refresh_token -d refresh_token= \ # -d client_id=kubernetes | jq -R 'split(".")[1] | @base64d | fromjson' # # The decoded access token must contain `"groups":["homelab-admins", ...]`. resource "zitadel_action" "groups_claim" { count = var.enable_groups_claim_action ? 1 : 0 org_id = data.zitadel_org.default.id name = "homelab-groups-claim" script = file(var.groups_claim_script) timeout = "5s" allowed_to_fail = false } # Both triggers are needed. The access-token trigger fills the JWT that # Kubernetes and MinIO read. The userinfo trigger fills the response that # Grafana, paperless and Forgejo read. resource "zitadel_trigger_actions" "groups_claim_access_token" { count = var.enable_groups_claim_action ? 1 : 0 org_id = data.zitadel_org.default.id flow_type = "FLOW_TYPE_CUSTOMISE_TOKEN" trigger_type = "TRIGGER_TYPE_PRE_ACCESS_TOKEN_CREATION" action_ids = [zitadel_action.groups_claim[0].id] } resource "zitadel_trigger_actions" "groups_claim_userinfo" { count = var.enable_groups_claim_action ? 1 : 0 org_id = data.zitadel_org.default.id flow_type = "FLOW_TYPE_CUSTOMISE_TOKEN" trigger_type = "TRIGGER_TYPE_PRE_USERINFO_CREATION" action_ids = [zitadel_action.groups_claim[0].id] }