# ============================================================================= # CLOUDFLARE : Traffic Policies : Firewall Policies : HTTP # ============================================================================= #========================================================== # Local Variables #========================================================== locals { precedence = { # HTTP (L7) Policies - AI Application Governance ai_tools_redirect = 24000 # Redirect unreviewed AI tools to Claude chatgpt_allow_log = 24100 # Allow ChatGPT with prompt logging # HTTP (L7) Policies - Content Filtering & DLP pdf_block = 25000 # Block PDF downloads for Sales Eng (identity-based DLP) gambling_block = 25100 # Block gambling websites (category blocking) } # Common rule settings for block policies default_block_settings_http = { block_page_enabled = false ip_categories = false ip_indicator_feeds = false insecure_disable_dnssec_validation = false } # Gateway policies configuration # Organized by policy type: then HTTP (L7) policies # Following Cloudflare best practices with 1000-spacing between major groups # Integrates with dashboard-managed policies at precedence: 1000-3000, 5000-20000, 36000-40000 gateway_policies = { #========================================================== # HTTP (L7) POLICIES # Application/Content-based filtering # Terraform precedence ranges: 24000-25100 # Dashboard precedence ranges: 13000-20000 # Note: Dashboard Do-Not-Inspect policies (13000-15000) evaluated before Terraform HTTP policies #========================================================== # AI Application Governance (Precedence: 24000-24100) redirect_ai_to_claude = { name = "HTTP - Redirect: Redirect users to claude.ai" description = "Redirect any unreviewed AI application to claude.ai instead" enabled = true action = "redirect" precedence = local.precedence.ai_tools_redirect filters = ["http"] traffic = "any(app.type.ids[*] in {25}) and any(app.statuses[*] == \"unreviewed\")" redirect_url = "https://claude.ai" notification_enabled = false } # Content Filtering & DLP (Precedence: 25000-25100) block_pdf_download = { name = "HTTP - Block: PDF Files download" description = "Block Downloading PDF Files for Sales Engineering group" enabled = false action = "block" precedence = local.precedence.pdf_block filters = ["http"] traffic = "any(http.download.file.types[*] in {\"pdf\"})" identity = "any(identity.saml_attributes[*] == \"groups=${var.okta_sales_eng_saml_group_name}\")" block_reason = "This download is blocked because it is a pdf file (not approved)" notification_enabled = true } block_gambling = { name = "HTTP - Block: Gambling websites" description = "Block Gambling website according to corporate policies (HTTP)." enabled = true action = "block" precedence = local.precedence.gambling_block filters = ["http"] traffic = "any(http.request.uri.content_category[*] in {99})" identity = "not(any(identity.saml_attributes[*] == \"groups=${var.okta_contractors_saml_group_name}\")) or not(identity.email == \"${var.okta_bob_user_login}\")" block_reason = "This website is blocked according to corporate policies (HTTP)" notification_enabled = true } allow_chatgpt_log = { name = "HTTP - Allow: ChatGPT logging" description = "Log ChatGPT requests" enabled = true action = "allow" precedence = local.precedence.chatgpt_allow_log filters = ["http"] traffic = "any(app.ids[*] == 1199) and any(app_control.controls[*] in {1652})" notification_enabled = false gen_ai_prompt_log = true } } } #========================================================== # Gateway Policies #========================================================== resource "cloudflare_zero_trust_gateway_policy" "policies" { for_each = local.gateway_policies account_id = local.cloudflare_account_id name = each.value.name description = each.value.description enabled = each.value.enabled action = each.value.action precedence = each.value.precedence filters = each.value.filters traffic = each.value.traffic # Optional fields identity = try(each.value.identity, null) device_posture = try(each.value.device_posture, null) rule_settings = merge( local.default_block_settings_http, { block_reason = try(each.value.block_reason, "") notification_settings = { enabled = try(each.value.notification_enabled, false) msg = try(each.value.block_reason, "") } redirect = try(each.value.redirect_url, null) != null ? { target_uri = each.value.redirect_url preserve_path_and_query = false include_context = false } : null gen_ai_prompt_log = try(each.value.gen_ai_prompt_log, null) != null ? { enabled = each.value.gen_ai_prompt_log } : null } ) }