data "authentik_flow" "default_authorization_flow" { slug = var.default_authorization_flow } data "authentik_flow" "default_authentication_flow" { slug = var.default_authentication_flow } data "authentik_flow" "default_invalidation_flow" { slug = var.default_invalidation_flow } # Root groups (without parent) resource "authentik_group" "root_groups" { for_each = { for k, v in var.groups : k => v if v.parent == null } name = each.value.name is_superuser = each.value.is_superuser attributes = jsonencode(each.value.attributes) } # Child groups (with parent) resource "authentik_group" "child_groups" { for_each = { for k, v in var.groups : k => v if v.parent != null } name = each.value.name is_superuser = each.value.is_superuser parent = authentik_group.root_groups[each.value.parent].id attributes = jsonencode(each.value.attributes) depends_on = [authentik_group.root_groups] } # Auto-created groups for proxy applications resource "authentik_group" "proxy_app_groups" { for_each = { for k, v in var.proxy_applications : k => v if v.create_group == true } name = "TF-${each.value.name} Users" is_superuser = false attributes = jsonencode({ notes = "Auto-created for ${each.value.name} application" app_slug = each.value.slug }) } # Auto-created groups for OAuth applications resource "authentik_group" "oauth_app_groups" { for_each = { for k, v in var.oauth_applications : k => v if v.create_group == true } name = "TF-${each.value.name} Users" is_superuser = false attributes = jsonencode({ notes = "Auto-created for ${each.value.name} application" app_slug = each.value.slug }) } resource "authentik_certificate_key_pair" "certificates" { for_each = var.certificates name = each.value.name certificate_data = each.value.certificate_data key_data = each.value.key_data } data "authentik_service_connection_kubernetes" "local_k8s" { name = "Local Kubernetes Cluster" } resource "authentik_flow" "flows" { for_each = var.flows name = each.value.name title = each.value.title slug = each.value.slug designation = each.value.designation policy_engine_mode = each.value.policy_engine_mode compatibility_mode = each.value.compatibility_mode layout = each.value.layout denied_action = each.value.denied_action } resource "authentik_property_mapping_provider_scope" "oidc_mappings" { for_each = { for k, v in var.property_mappings : k => v if v.oidc_scope != null } name = each.value.name scope_name = each.value.oidc_scope expression = each.value.expression } resource "authentik_property_mapping_provider_saml" "saml_mappings" { for_each = { for k, v in var.property_mappings : k => v if v.saml_name != null } name = each.value.name saml_name = each.value.saml_name expression = each.value.expression } module "oauth_applications" { source = "./modules/oauth-provider" for_each = var.oauth_applications name = each.value.name app_name = each.value.name app_slug = each.value.slug app_group = each.value.group client_id = each.value.client_id authorization_flow = try(authentik_flow.flows[each.value.authorization_flow].id, data.authentik_flow.default_authorization_flow.id) invalidation_flow = data.authentik_flow.default_invalidation_flow.id redirect_uris = each.value.redirect_uris client_type = each.value.client_type include_claims_in_id_token = each.value.include_claims_in_id_token access_code_validity = each.value.access_code_validity access_token_validity = each.value.access_token_validity refresh_token_validity = each.value.refresh_token_validity property_mappings = each.value.property_mappings signing_key = each.value.signing_key policy_engine_mode = each.value.policy_engine_mode meta_description = each.value.meta_description meta_launch_url = each.value.meta_launch_url meta_icon = each.value.meta_icon scope_mappings = each.value.scope_mappings # Access control - only pass explicitly defined groups access_groups = [ for group_key in each.value.access_groups : try( authentik_group.root_groups[group_key].id, authentik_group.child_groups[group_key].id ) ] } module "proxy_applications" { source = "./modules/proxy-provider" for_each = var.proxy_applications name = each.value.name app_name = each.value.name app_slug = each.value.slug app_group = each.value.group external_host = each.value.external_host internal_host = each.value.internal_host internal_host_ssl_validation = each.value.internal_host_ssl_validation authorization_flow = try(authentik_flow.flows[each.value.authorization_flow].id, data.authentik_flow.default_authorization_flow.id) invalidation_flow = data.authentik_flow.default_invalidation_flow.id mode = each.value.mode intercept_header_auth = each.value.intercept_header_auth basic_auth_enabled = each.value.basic_auth_enabled basic_auth_user_attribute = each.value.basic_auth_username_attribute basic_auth_password_attribute = each.value.basic_auth_password_attribute cookie_domain = each.value.cookie_domain skip_path_regex = each.value.skip_path_regex policy_engine_mode = each.value.policy_engine_mode meta_description = each.value.meta_description meta_launch_url = each.value.meta_launch_url meta_icon = each.value.meta_icon # Access control - only pass explicitly defined groups access_groups = [ for group_key in each.value.access_groups : try( authentik_group.root_groups[group_key].id, authentik_group.child_groups[group_key].id ) ] } # Binding auto-created groups to their applications resource "authentik_policy_binding" "auto_group_bindings" { for_each = { for k, v in var.proxy_applications : k => v if v.create_group == true } target = module.proxy_applications[each.key].application_uuid group = authentik_group.proxy_app_groups[each.key].id order = 100 depends_on = [ module.proxy_applications, authentik_group.proxy_app_groups ] } # Binding auto-created groups to their OAuth applications resource "authentik_policy_binding" "oauth_auto_group_bindings" { for_each = { for k, v in var.oauth_applications : k => v if v.create_group == true } target = module.oauth_applications[each.key].application_uuid group = authentik_group.oauth_app_groups[each.key].id order = 100 depends_on = [ module.oauth_applications, authentik_group.oauth_app_groups ] } module "saml_applications" { source = "./modules/saml-provider" for_each = var.saml_applications name = each.value.name app_name = each.value.name app_slug = each.value.slug app_group = each.value.group authorization_flow = try(authentik_flow.flows[each.value.authorization_flow].id, data.authentik_flow.default_authorization_flow.id) invalidation_flow = data.authentik_flow.default_invalidation_flow.id acs_url = each.value.acs_url issuer = each.value.issuer audience = each.value.audience sp_binding = each.value.sp_binding signing_key = each.value.signing_key property_mappings = [for pm in each.value.property_mappings : authentik_property_mapping_provider_saml.saml_mappings[pm].id] name_id_mapping = each.value.name_id_mapping != null ? authentik_property_mapping_provider_saml.saml_mappings[each.value.name_id_mapping].id : null assertion_valid_not_before = each.value.assertion_valid_not_before assertion_valid_not_on_or_after = each.value.assertion_valid_not_on_or_after session_valid_not_on_or_after = each.value.session_valid_not_on_or_after policy_engine_mode = each.value.policy_engine_mode meta_description = each.value.meta_description meta_launch_url = each.value.meta_launch_url meta_icon = each.value.meta_icon } locals { oauth_outpost_assignments = { for app_key, app in var.oauth_applications : app_key => app.outpost if app.outpost != null } proxy_outpost_assignments = { for app_key, app in var.proxy_applications : app_key => app.outpost if app.outpost != null } outpost_providers = { for outpost_key, outpost in var.outposts : outpost_key => concat( [for app_key, app_outpost in local.oauth_outpost_assignments : module.oauth_applications[app_key].provider_id if app_outpost == outpost_key], [for app_key, app_outpost in local.proxy_outpost_assignments : module.proxy_applications[app_key].provider_id if app_outpost == outpost_key] ) } } resource "authentik_outpost" "outposts" { for_each = { for k, v in var.outposts : k => v if length(lookup(local.outpost_providers, k, [])) > 0 } name = each.value.name type = "proxy" protocol_providers = local.outpost_providers[each.key] service_connection = data.authentik_service_connection_kubernetes.local_k8s.id config = jsonencode({ log_level = "info" docker_labels = null authentik_host = var.authentik_url docker_network = null container_image = null docker_map_ports = true refresh_interval = "minutes=5" kubernetes_replicas = 1 kubernetes_namespace = "authentik" authentik_host_browser = "" object_naming_template = "ak-outpost-%(name)s" authentik_host_insecure = false kubernetes_json_patches = null kubernetes_service_type = "ClusterIP" kubernetes_image_pull_secrets = [] kubernetes_ingress_class_name = null kubernetes_disabled_components = [] kubernetes_ingress_annotations = {} kubernetes_ingress_secret_name = "authentik-outpost-tls" }) depends_on = [ module.oauth_applications, module.proxy_applications ] }