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.
19 lines
867 B
Terraform
19 lines
867 B
Terraform
# API applications — the machine-token surface.
|
|
#
|
|
# ZITADEL keeps two different objects apart: an OIDC application is for a
|
|
# browser flow, and an API application is what a client_credentials / JWT-profile
|
|
# caller presents. Authentik modelled both with one provider, so the plan §1.1
|
|
# row 1 ("OIDC app + machine user") needs one of each here.
|
|
#
|
|
# The gateway signs its token request with the machine key from machines.tf, so
|
|
# the auth method is PRIVATE_KEY_JWT. No secret is stored for it.
|
|
|
|
resource "zitadel_application_api" "machine" {
|
|
for_each = { for name, spec in local.machine_users : name => spec if contains(keys(var.api_app_consumers), name) }
|
|
|
|
org_id = data.zitadel_org.default.id
|
|
project_id = zitadel_project_v2.homelab.id
|
|
name = "${each.key}-machine"
|
|
auth_method_type = "API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT"
|
|
}
|