locals { longhorn_oauth2_proxy_redirect_uri = "${trim(var.longhorn_base_url, "/")}/oauth2/callback" longhorn_zitadel_roles = { longhorn_admin = { display_name = "Longhorn administrator" group = "Longhorn" } } longhorn_zitadel_role_keys = keys(local.longhorn_zitadel_roles) } resource "zitadel_project_role" "longhorn" { for_each = local.longhorn_zitadel_roles org_id = zitadel_org.primary.id project_id = zitadel_project.services.id role_key = each.key display_name = each.value.display_name group = each.value.group } resource "zitadel_application_oidc" "longhorn" { org_id = zitadel_org.primary.id project_id = zitadel_project.services.id name = "Longhorn" redirect_uris = [local.longhorn_oauth2_proxy_redirect_uri] response_types = ["OIDC_RESPONSE_TYPE_CODE"] grant_types = ["OIDC_GRANT_TYPE_AUTHORIZATION_CODE", "OIDC_GRANT_TYPE_REFRESH_TOKEN"] post_logout_redirect_uris = [trim(var.longhorn_base_url, "/")] app_type = "OIDC_APP_TYPE_WEB" auth_method_type = "OIDC_AUTH_METHOD_TYPE_BASIC" version = "OIDC_VERSION_1_0" clock_skew = "0s" dev_mode = false access_token_type = "OIDC_TOKEN_TYPE_BEARER" access_token_role_assertion = false id_token_role_assertion = true id_token_userinfo_assertion = true additional_origins = [] skip_native_app_success_page = false } resource "random_password" "longhorn_oauth2_proxy_cookie_secret" { length = 32 special = false } resource "vault_kv_secret_v2" "longhorn_oauth2_proxy" { mount = var.vault_kv_mount name = var.longhorn_oauth2_proxy_vault_path data_json = jsonencode({ OAUTH2_PROXY_CLIENT_ID = zitadel_application_oidc.longhorn.client_id OAUTH2_PROXY_CLIENT_SECRET = zitadel_application_oidc.longhorn.client_secret OAUTH2_PROXY_COOKIE_SECRET = random_password.longhorn_oauth2_proxy_cookie_secret.result client_id = zitadel_application_oidc.longhorn.client_id client_secret = zitadel_application_oidc.longhorn.client_secret discovery_url = "https://${var.zitadel_domain}/.well-known/openid-configuration" redirect_uri = local.longhorn_oauth2_proxy_redirect_uri }) # Vault is source of truth after first write. OIDC credential rotation is explicit. lifecycle { ignore_changes = [data_json] } }