feat(iam): declare Zitadel identity objects in Terraform
Adds terraform/zitadel: the provisioning half the ArgoCD wiring left open. It declares 1 project, 19 project roles, 12 OIDC applications, 5 machine users plus keys, one API application for the gateway, project grants, per-agent claim metadata, and a disabled groups-claim action. Facts established while writing it: - Client IDs cannot be preserved. ZITADEL v4.19.2 CreateOIDCApplicationRequest has no client_id field, and provider 3.8.7 rejects a settable application id (terraform validate reports "Invalid or unknown key"). Plan §3.2 assumed a client_id-preserving re-point; every consumer now also changes client ID. - Role keys equal the existing group names, so the groups claim can be byte-identical and no RBAC file changes. v4.19.2 allows role keys of 1-200 characters with no character-set restriction. - Machine users get JWT profile keys, not passwords. Per-agent claims move to user metadata and reach tokens only through the groups-claim action. - The action stays gated: enable_groups_claim_action defaults to false because the action runtime API is unverified. Two validations stop a null script from reaching file(). Checks: terraform fmt -check -recursive clean, terraform validate 0 errors, plan reaches only the expected missing-credentials error, structural gate 0 error / 0 warning, and one reviewer round: BLOCK on a plan-time fileexists(null) and on the missing api-gw machine path, both fixed, re-reviewed to SIGN-OFF. State is local and git-ignored; it carries generated client secrets and machine keys. Move it to MinIO before a second operator applies. Not applied: no Zitadel instance is running yet.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# Outputs feed two things: the SOPS re-point of consumer secrets (§3.2, §6.9)
|
||||
# and the machine-key handoff to each agent workload (§5.3). Every value that can
|
||||
# authenticate a client is marked sensitive, so `terraform output` prints a
|
||||
# placeholder until you ask for it explicitly.
|
||||
|
||||
output "org_id" {
|
||||
description = "Organization that owns the project, roles and applications."
|
||||
value = data.zitadel_org.default.id
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
description = "Project ID, which ZITADEL puts in the access-token `aud` claim."
|
||||
value = zitadel_project_v2.homelab.id
|
||||
}
|
||||
|
||||
output "client_ids" {
|
||||
description = "client_id per consumer. Compare against the Authentik values: any difference means the consumer config must change too."
|
||||
value = { for name, app in zitadel_application_v2.oidc : name => app.oidc[0].client_id }
|
||||
}
|
||||
|
||||
output "client_secrets" {
|
||||
description = "Generated client secret per consumer. Write these into the existing SOPS files; never into git."
|
||||
value = { for name, app in zitadel_application_v2.oidc : name => app.oidc[0].client_secret }
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "api_app_client_ids" {
|
||||
description = "client_id of each API application (machine-token surface)."
|
||||
value = { for name, app in zitadel_application_api.machine : name => app.client_id }
|
||||
}
|
||||
|
||||
output "machine_user_ids" {
|
||||
description = "ZITADEL user ID per machine user."
|
||||
value = { for name, user in zitadel_machine_user.agent : name => user.id }
|
||||
}
|
||||
|
||||
output "machine_keys" {
|
||||
description = "JWT profile key JSON per machine user. Mount as a file; do not pass through the environment."
|
||||
value = { for name, key in zitadel_machine_key.agent : name => key.key_details }
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "groups_claim_enabled" {
|
||||
description = "Whether the groups-claim action and its triggers exist. False means Option A is not yet in place and no consumer may move."
|
||||
value = var.enable_groups_claim_action
|
||||
}
|
||||
Reference in New Issue
Block a user