59 lines
2.5 KiB
Terraform
59 lines
2.5 KiB
Terraform
# 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:<group>), 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=<t> \
|
||
|
|
# -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]
|
||
|
|
}
|