> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Coraza WAF

> Deploy Coraza WAF on Control Plane using the Template Catalog. Covers configuration, OWASP CRS rules, and reverse proxy setup for filtering traffic to target workloads.

## Overview

Coraza is an open-source Web Application Firewall (WAF) that integrates the OWASP Core Rule Set (CRS) for comprehensive protection against common web attacks. This template uses the [Coraza Caddy](https://github.com/coreruleset/coraza-crs-docker) image, which runs Coraza as a plugin inside the Caddy web server to handle request inspection and proxying. It sits in front of a target workload, filtering all incoming requests before forwarding them.

### What Gets Created

* **Workload** — A Coraza WAF container running with OWASP CRS, configured as a reverse proxy to your target workload.
* **Secrets** — A startup script secret that configures the Caddy reverse proxy, and a custom rules secret (suffixed `-coraza-custom-rules`) containing an initial example rule, editable after installation to define your own WAF policies.
* **Identity & Policy** — An identity bound to the workload with `reveal` access to the startup and custom rules secrets.

<Note>
  This template does not create a GVC. You must deploy it into an existing GVC alongside your target workload.
</Note>

## Prerequisites

The target workload must be reachable from the Coraza WAF workload. Before installing, ensure the target workload's internal access is configured to allow traffic from the WAF:

* Set the target workload's `internal_access` to `same-gvc`, `same-org`, or use `workload-list` to explicitly allow the Coraza workload.

## Installation

To install, follow the instructions for your preferred method:

<CardGroup cols={2}>
  <Card title="UI" href="/template-catalog/install-manage/ui" icon="laptop">
    Browse, install, and manage templates visually
  </Card>

  <Card title="CLI" href="/template-catalog/install-manage/cli" icon="terminal">
    Manage templates from your terminal
  </Card>

  <Card title="Terraform" href="/template-catalog/install-manage/terraform" icon={<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><g fill-rule="evenodd"><path d="M77.941 44.5v36.836L46.324 62.918V26.082zm0 0" fill="#5c4ee5"/><path d="M81.41 81.336l31.633-18.418V26.082L81.41 44.5zm0 0" fill="#4040b2"/><path d="M11.242 42.36L42.86 60.776V23.941L11.242 5.523zm0 0M77.941 85.375L46.324 66.957v36.82l31.617 18.418zm0 0" fill="#5c4ee5"/></g></svg>}>
    Declare templates in your Terraform configurations
  </Card>

  <Card
    title="Pulumi"
    href="/template-catalog/install-manage/pulumi"
    icon={<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="Pulumi-Icon--Streamline-Svg-Logos" height="24" width="24">
    <desc>
        Pulumi Icon Streamline Icon: https://streamlinehq.com
    </desc>
    <path fill="#f26e7e" d="M4.683025 13.3318c0.869125 -0.5018 0.870575 -2.1264 0.003225 -3.62865s-2.27504 -2.313275 -3.1441725 -1.811475C0.672945 8.3935 0.6715 10.0181 1.53885 11.52035c0.86735 1.502275 2.27505 2.313275 3.144175 1.81145Zm0.0052 3.2167c0.86735 1.502275 0.865925 3.126875 -0.003225 3.628675 -0.86915 0.5018 -2.2768275 -0.309225 -3.144175 -1.81145 -0.8673525 -1.50225 -0.8659075 -3.126875 0.003225 -3.628675 0.8691325 -0.5018 2.276825 0.309225 3.144175 1.81145Zm5.922875 3.4243c0.86735 1.50225 0.8659 3.126775 -0.003225 3.62875 -0.869125 0.501775 -2.27685 -0.309325 -3.1442 -1.81155 -0.867325 -1.50225 -0.865875 -3.12685 0.00325 -3.628675 0.869125 -0.5018 2.276825 0.309225 3.144175 1.811475Zm-0.001925 -6.845275c0.86735 1.50225 0.8659 3.12685 -0.003225 3.628675 -0.869125 0.5018 -2.276825 -0.309225 -3.144175 -1.811475 -0.86735 -1.50225 -0.8659 -3.12685 0.003225 -3.62865 0.869125 -0.501825 2.276825 0.3092 3.144175 1.81145Z" stroke-width="0.25"></path>
    <path fill="#8a3391" d="M22.45775 11.524125c0.86725 -1.502225 0.865925 -3.12685 -0.003225 -3.62865 -0.869125 -0.501825 -2.276825 0.3092 -3.144175 1.811475 -0.86735 1.50225 -0.8659 3.126825 0.003225 3.62865 0.869125 0.501825 2.276825 -0.3092 3.144175 -1.811475Zm0.000175 3.2151c0.869075 0.5018 0.870625 2.1264 0.003225 3.62865 -0.86735 1.50225 -2.27505 2.313275 -3.144175 1.81145 -0.869125 -0.5018 -0.870575 -2.126425 -0.003225 -3.62865 0.86735 -1.50225 2.27505 -2.313275 3.144175 -1.81145ZM16.536225 18.157875c0.86915 0.501825 0.8706 2.126425 0.00325 3.628675 -0.86735 1.502125 -2.275075 2.313225 -3.1442 1.81145 -0.869125 -0.50175 -0.870575 -2.126425 -0.003225 -3.62865 0.867375 -1.502275 2.27505 -2.3133 3.144175 -1.811475Zm-0.003325 -6.843775c0.869125 0.5018 0.870575 2.126425 0.003225 3.628675s-2.27505 2.313275 -3.1442 1.811475c-0.869125 -0.501825 -0.870575 -2.126425 -0.003225 -3.628675 0.86735 -1.502275 2.27505 -2.313275 3.1442 -1.811475Z" stroke-width="0.25"></path>
    <path fill="#f7bf2a" d="M15.138225 2.06721c0 1.003615 -1.40625 1.817215 -3.14095 1.817215 -1.7347 0 -3.14095 -0.8136 -3.14095 -1.817215C8.856325 1.06359 10.262575 0.25 11.997275 0.25c1.7347 0 3.14095 0.81359 3.14095 1.81721ZM9.2166 5.482375c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172s1.40625 -1.817225 3.14095 -1.817225c1.7347 0 3.14095 0.8136 3.14095 1.817225Zm8.71005 1.8172c1.7347 0 3.14095 -0.813575 3.14095 -1.8172s-1.40625 -1.817225 -3.14095 -1.817225c-1.7347 0 -3.14095 0.8136 -3.14095 1.817225s1.40625 1.8172 3.14095 1.8172Zm-2.788425 1.605625c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172 0 -1.0036 1.40625 -1.8172 3.14095 -1.8172 1.7347 0 3.14095 0.8136 3.14095 1.8172Z" stroke-width="0.25"></path>
    </svg>}
  >
    Declare templates in your Pulumi programs
  </Card>
</CardGroup>

## Configuration

The default `values.yaml` for this template:

```yaml theme={null}
image: ghcr.io/coreruleset/coraza-crs@sha256:eed7280e0de4820507b500b1ee10de820c175165d5cce329609bf34f32977af8

# MUST BE CHANGED
targetWorkload: my-workload.my-gvc.cpln.local # Internal name of the workload to proxy traffic to

targetPort: 8080 # Port of the target workload

WAFPort: 80 # Port on the WAF workload exposed to the internet

resources:
  cpu: 50m
  memory: 128Mi

multiZone: false

diskBodyInspection: true # When true, request bodies exceeding the in-memory limit are buffered to disk for inspection
```

### Target Workload

* `targetWorkload` — The internal DNS name of the workload to proxy traffic to. Uses the format `WORKLOAD_NAME.GVC_NAME.cpln.local`. **This must be changed before deploying.**
* `targetPort` — The port on the target workload that Coraza should forward requests to.
* `WAFPort` — The port on the Coraza workload exposed to the internet (default `80`).

### Resources

* `resources.cpu` / `resources.memory` — CPU and memory allocated to the WAF workload.
* `multiZone` — When `true`, deploys replicas across multiple zones for higher availability.

<Note>
  Not all locations support multi-zone deployments. Confirm that your target location supports multi-zone before enabling this option.
</Note>

### Body Inspection

* `diskBodyInspection` — Controls how request bodies larger than the 512KB in-memory limit are handled:

| Value            | Behavior                                                                                                                                               |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `true` (default) | Bodies exceeding 512KB are buffered to disk at `/tmp/coraza`, enabling full inspection up to 12.5MB                                                    |
| `false`          | All body inspection stays in memory; bodies up to 12.5MB are held in memory, avoiding disk I/O at the cost of higher memory pressure on large requests |

### Custom Rules

After installation, custom WAF rules can be added by editing the secret named `<release-name>-coraza-custom-rules`. The secret includes an example rule to get started:

```text theme={null}
SecRule REQUEST_URI "@rx attack" "id:1001,phase:1,deny,msg:'Blocked attack attempt'"
```

<Note>
  After modifying the custom rules secret, you must restart the workload replicas for the changes to take effect.
</Note>

### Logging

All Coraza logs are sent to `/dev/stdout` and are readable in the Control Plane built-in logging interface. Logging behavior can be adjusted through environment variables in the workload configuration after installation.

## External References

<CardGroup cols={2}>
  <Card title="OWASP Coraza Documentation" icon="book" href="https://coraza.io/docs/tutorials/introduction/">
    Official Coraza WAF documentation and tutorials
  </Card>

  <Card title="OWASP CRS Documentation" icon="shield" href="https://coreruleset.org/docs/">
    Core Rule Set documentation and custom rule authoring
  </Card>

  <Card title="Coraza CRS Docker" icon="github" href="https://github.com/coreruleset/coraza-crs-docker">
    Coraza CRS Docker image reference
  </Card>

  <Card title="Coraza Template" icon="github" href="https://github.com/controlplane-com/templates/tree/main/coraza">
    View the source files, default values, and chart definition
  </Card>
</CardGroup>
