---
title: Enabling App and API Protection for Istio
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > App and API Protection > Enabling App and API
  Protection > Set up App and API Protection on Kubernetes > Enabling App and
  API Protection for Istio
---

# Enabling App and API Protection for Istio

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ().
{% /alert %}

{% /callout %}

{% callout %}
##### App and API Protection for Istio is in Preview

To try the preview of App and API Protection for Istio, use the following setup instructions.
{% /callout %}

You can enable App and API Protection within an Istio service mesh to inspect and protect traffic at the edge of your infrastructure. This works at the Istio Ingress Gateway or at the sidecar level.

## Prerequisites{% #prerequisites %}

Before you begin, verify that you have the following:

- A running Kubernetes cluster with [Istio](https://istio.io/) installed.
- The [Datadog Agent is installed and configured](https://docs.datadoghq.com/containers/kubernetes/installation.md?tab=datadogoperator) in your Kubernetes cluster.
  - Enable and configure [Remote Configuration](https://docs.datadoghq.com/agent/remote_config.md?tab=helm#enabling-remote-configuration) to enable blocking attackers through the Datadog UI.
  - Enable [APM](https://docs.datadoghq.com/tracing/guide/setting_up_apm_with_kubernetes_service.md?tab=datadogoperator) in the Agent. This allows the security processor service to send its own traces to the Agent.
    - Optionally, enable the [Cluster Agent Admission Controller](https://docs.datadoghq.com/tracing/guide/setting_up_apm_with_kubernetes_service.md?tab=datadogoperator#cluster-agent-admission-controller) to automatically inject the Datadog Agent host information to the App and API Protection security processor service.

## Automated configuration with App and API Protection for Kubernetes{% #automated-configuration-with-app-and-api-protection-for-kubernetes %}

{% alert level="info" %}
Automated configuration uses **sidecar mode**: the security processor runs as a container injected into your Istio gateway pods. No separate processor deployment is needed.

For **external mode** setup, see [App and API Protection for Kubernetes](https://docs.datadoghq.com/containers/kubernetes/appsec.md).
{% /alert %}

### Setup{% #setup %}

Enable automatic configuration using Helm or the Datadog Operator.

{% tab title="Helm" %}
Add the following to your `values.yaml`:

```yaml
datadog:
  appsec:
    injector:
      enabled: true
      # mode defaults to "sidecar" when omitted
```

Install or upgrade the Datadog Helm chart:

```bash
helm upgrade -i datadog-agent datadog/datadog -f values.yaml
```

{% /tab %}

{% tab title="Datadog Operator" %}
Add the annotation to your `DatadogAgent` resource to enable the feature, and set the mode using `spec.override.clusterAgent.env`:

```yaml
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
  annotations:
    agent.datadoghq.com/appsec.injector.enabled: "true"
spec:
  override:
    clusterAgent:
      env:
        - name: DD_CLUSTER_AGENT_APPSEC_INJECTOR_MODE
          value: "sidecar"
```

Apply with:

```bash
kubectl apply -f datadog-agent.yaml
```

{% /tab %}

After you enable this, the Datadog Cluster Agent:

- Injects a sidecar processor container into your Istio gateway pods
- Creates `EnvoyFilter` resources to route traffic to the co-located sidecar processor
- Monitors for new Istio gateways and configures them automatically

**Verify** the configuration by checking for created filters:

```bash
kubectl get envoyfilter -n istio-system
```

For sidecar resource tuning and troubleshooting, see [App and API Protection for Kubernetes](https://docs.datadoghq.com/containers/kubernetes/appsec.md).

## Manual configuration (alternative){% #manual-configuration-alternative %}

For fine-grained control over specific gateways or sidecars, use the manual setup below. This involves two steps:

1. Deploying the Datadog security processor service.
1. Configuring an `EnvoyFilter` to direct traffic from your Istio Ingress Gateway (or sidecars) to this service.

### Step 1: Deploy the Datadog security processor service{% #step-1-deploy-the-datadog-security-processor-service %}

This gRPC server receives requests and responses from Envoy for App and API Protection analysis.

Deploy it in a namespace accessible by your Istio Ingress Gateway. The Docker image is on the [Datadog Go tracer GitHub Registry](https://github.com/DataDog/dd-trace-go/pkgs/container/dd-trace-go%2Fservice-extensions-callout).

Example manifest (`datadog-aap-extproc-service.yaml`):

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: datadog-aap-extproc-deployment
  namespace: <your-preferred-namespace> # Change to your preferred namespace, ensure it's resolvable by the Envoy proxy
  labels:
    app: datadog-aap-extproc
spec:
  replicas: 1 # Adjust replica count based on your load
  selector:
    matchLabels:
      app: datadog-aap-extproc
  template:
    metadata:
      labels:
        app: datadog-aap-extproc
    spec:
      containers:
      - name: datadog-aap-extproc-container
        image: ghcr.io/datadog/dd-trace-go/service-extensions-callout:v2.2.2 # Replace with the latest released version
        ports:
        - name: grpc
          containerPort: 443 # Default gRPC port for the security processor
        - name: health
          containerPort: 80  # Default health check port
        env:
        # ---- Optional: Agent Configuration ----
        # If you enabled the Cluster Agent Admission Controller, you can skip this section as the Agent host information is automatically injected.
        # Otherwise, configure the address of your Datadog Agent for the security processor
        - name: DD_AGENT_HOST
          value: "<your-datadog-agent-service>.<your-datadog-agent-namespace>.svc.cluster.local"
        - name: DD_TRACE_AGENT_PORT # Optional if your Agent's trace port is the default 8126
          value: "8126"

        readinessProbe:
          httpGet:
            path: /
            port: health
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /
            port: health
          initialDelaySeconds: 15
          periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
  name: datadog-aap-extproc-service # This name will be used in the EnvoyFilter configuration
  namespace: <your-preferred-namespace> # Change to your preferred namespace, ensure it's resolvable by the Envoy proxy
  labels:
    app: datadog-aap-extproc
spec:
  ports:
  - name: grpc
    port: 443
    targetPort: grpc
    protocol: TCP
  selector:
    app: datadog-aap-extproc
  type: ClusterIP
```

#### Configuration options for the security processor{% #configuration-options-for-the-security-processor %}

The Datadog security processor exposes some settings:

| Environment variable                      | Default value       | Description                                                                                                                                                                                                                                                                          |
| ----------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_SERVICE_EXTENSION_HOST`               | `0.0.0.0`           | gRPC server listening address.                                                                                                                                                                                                                                                       |
| `DD_SERVICE_EXTENSION_PORT`               | `443`               | gRPC server port.                                                                                                                                                                                                                                                                    |
| `DD_SERVICE_EXTENSION_HEALTHCHECK_PORT`   | `80`                | HTTP server port for health checks.                                                                                                                                                                                                                                                  |
| `DD_APPSEC_BODY_PARSING_SIZE_LIMIT`       | `0`                 | Maximum size of the bodies to be processed in bytes. If set to `0`, the bodies are not processed. The recommended value is `10000000` (10MB). (To fully enable body processing, the `allow_mode_override` option should also be set in the External Processing filter configuration) |
| `DD_SERVICE_EXTENSION_OBSERVABILITY_MODE` | `false`             | Enable asynchronous analysis of requests. This also disables blocking capabilities. (To fully enable observability mode, this option should also be set in the External Processing filter configuration)                                                                             |
| `DD_SERVICE`                              | `serviceextensions` | Service name shown in the Datadog UI.                                                                                                                                                                                                                                                |

Configure the connection from the security processor to the Datadog Agent using these environment variables:

| Environment variable  | Default value | Description                                     |
| --------------------- | ------------- | ----------------------------------------------- |
| `DD_AGENT_HOST`       | `localhost`   | Hostname or IP of your Datadog Agent.           |
| `DD_TRACE_AGENT_PORT` | `8126`        | Port of the Datadog Agent for trace collection. |

The security processor is built on top of the [Datadog Go Tracer](https://github.com/DataDog/dd-trace-go) and inherits all of its environment variables. See [Configuring the Go Tracing Library](https://docs.datadoghq.com/tracing/trace_collection/library_config/go.md) and [App and API Protection Library Configuration](https://docs.datadoghq.com/security/application_security/policies/library_configuration.md).

{% alert level="info" %}
Because the Datadog security processor is built on top of the Datadog Go tracer, it generally follows the same release process as the tracer, and its Docker images are tagged with the corresponding tracer version (for example, `v2.2.2`). In some cases, early release versions might be published between official tracer releases, and these images are tagged with a suffix such as `-docker.1`.
{% /alert %}

### Step 2: Configure an EnvoyFilter{% #step-2-configure-an-envoyfilter %}

Create an `EnvoyFilter` resource to send traffic from your Istio Ingress Gateway or sidecar proxies to the `datadog-aap-extproc-service` you deployed.

{% tab title="Istio Ingress Gateway" %}
Applies App and API Protection to all traffic through your Istio Ingress Gateway (North-South traffic).

The following example manifest (`datadog-aap-gateway-filter.yaml`) targets the default Istio Ingress Gateway in the `istio-system` namespace with the label `istio: ingressgateway`.

**Note**: Read the provided example configuration carefully and adapt it to match your infrastructure and environment. You can find more configuration options in the [Envoy security processor documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/ext_proc.proto).

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: datadog-aap-gateway-filter
  namespace: <your-preferred-namespace> # Change to your preferred namespace, ensure it's resolvable by the Envoy proxy
spec:
  ## If workloadSelector is omitted, the following patches apply to Gateway pods in this EnvoyFilter's namespace
  ## Use workloadSelector to target a specific Gateway instance.
  # workloadSelector:
  #   labels:
  #     istio: ingressgateway # Label for the default Istio Gateway implementation
  configPatches:
    # Patch to add the External Processing Filter to the Gateway's HTTP connection manager
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        # Insert this filter before the router filter. This filter needs to be the earliest filter in the chain to process malicious traffic before the data is sent to an application.
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.ext_proc
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
            grpc_service:
              envoy_grpc:
                cluster_name: datadog_aap_ext_proc_cluster

              ## Mandatory: Correctly show the service as an Envoy proxy in the UI.
              initial_metadata:
                - key: x-datadog-envoy-integration
                  value: '1'

              ## A timeout configuration for the grpc connection exist but is not useful in our case.
              ## This timeout is for all the request lifetime. A timeout on the route is preferred.
              #timeout: 0s

            ## Optional: Enable fail open mode. Default is false.
            ## Normally, if the security processor fails or times out, the filter fails and Envoy
            ## returns a 5xx error to the downstream client. Setting this to true allows requests
            ## to continue without error if a failure occurs.
            failure_mode_allow: true # It won't cause 5xx error if an error occurs.

            ## Mandatory: Only enable the request and response header modes.
            ## If you want to enable body processing, please see the section below.
            processing_mode:
              request_header_mode: SEND
              response_header_mode: SEND

            ## Optional for headers analysis only but **mandatory** for body processing.
            ## The security processor can dynamically override the processing mode as needed instructing
            ## Envoy to forward request and response bodies to the security processor. Body processing is
            ## enabled when DD_APPSEC_BODY_PARSING_SIZE_LIMIT is set on the security processor container.
            allow_mode_override: true

            ## Optional: Set a timeout by processing message. Default is 200ms.
            ## There is a maxium of 2 messages per requests with headers only and 4 messages maximum
            ## with body processing enabled.
            ## Note: This timeout also includes the data communication between Envoy and the security processor.
            ## Optional: When the body processing is enabled, the timeout should be adjusted to accommodate
            ## the additional possible processing time. Larger payloads will require a longer timeout. 
            #message_timeout: 200ms

            ## Optional: Enable asynchronous mode analysis. Default is false.
            ## This mode will disable all blocking capabilities. The security processor should also be
            ## configured with the DD_SERVICE_EXTENSION_OBSERVABILITY_MODE environment variable.
            ## Beware, there is no flow control implemented in Envoy
            ## (cf https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/ext_proc.proto#envoy-v3-api-field-extensions-filters-http-ext-proc-v3-externalprocessor-observability-mode)
            #observability_mode: true
            ## Optional: When in asynchronous mode, the message_timeout is not used. This deferred
            ## timeout starts when the http request is finished, to let the security processor
            ## process all processing messages. Default is 5s.
            #deferred_close_timeout: 5s


    # Patch to add the cluster definition for the Datadog External Processing service
    - applyTo: CLUSTER
      match:
        context: GATEWAY
        cluster:
          service: "*"
      patch:
        operation: ADD
        value:
          name: "datadog_aap_ext_proc_cluster" # A unique name for this cluster configuration
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          http2_protocol_options: {}
          transport_socket:
            name: envoy.transport_sockets.tls
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
              sni: "localhost"
          load_assignment:
            cluster_name: "datadog_aap_ext_proc_cluster"
            endpoints:
            - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      # Address of the Datadog security processor service
                      address: "datadog-aap-extproc-service.<your-preferred-namespace>.svc.cluster.local" # Adjust if your service name or namespace is different
                      port_value: 443
```

{% /tab %}

{% tab title="Sidecar" %}
This configuration applies App and API Protection to specific pods within your service mesh by targeting their Istio sidecar proxies. This allows for more granular control over which services are protected.

Here is an example manifest (`datadog-aap-sidecar-filter.yaml`) that targets pods with the label `app: <your-app-label>` in the namespace `<your-application-namespace>`. You must update these settings to match your specific application.

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: datadog-aap-sidecar-filter
  namespace: <your-application-namespace> # Namespace of your application
spec:
  workloadSelector:
    labels:
      app: <your-app-label> # Label of your application pods
  configPatches:
    # Patch to add the External Processing HTTP Filter to the Sidecar's connection manager
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.ext_proc
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
            grpc_service:
              envoy_grpc:
                cluster_name: datadog_aap_ext_proc_cluster

              ## Mandatory: Correctly show the service as an Envoy proxy in the UI.
              initial_metadata:
                - key: x-datadog-envoy-integration
                  value: '1'

              ## A timeout configuration for the grpc connection exist but is not useful in our case.
              ## This timeout is for all the request lifetime. A timeout on the route is preferred.
              #timeout: 0s

            ## Optional: Enable fail open mode. Default is false.
            ## Normally, if the security processor fails or times out, the filter fails and Envoy
            ## returns a 5xx error to the downstream client. Setting this to true allows requests
            ## to continue without error if a failure occurs.
            failure_mode_allow: true # It won't cause 5xx error if an error occurs.

            ## Mandatory: Only enable the request and response header modes.
            ## If you want to enable body processing, please see the section below.
            processing_mode:
              request_header_mode: SEND
              response_header_mode: SEND

            ## Optional for headers analysis only but **mandatory** for body processing.
            ## The security processor can dynamically override the processing mode as needed instructing
            ## Envoy to forward request and response bodies to the security processor. Body processing is
            ## enabled when DD_APPSEC_BODY_PARSING_SIZE_LIMIT is set on the security processor container.
            allow_mode_override: true

            ## Optional: Set a timeout by processing message. Default is 200ms.
            ## There is a maxium of 2 messages per requests with headers only and 4 messages maximum
            ## with body processing enabled.
            ## Note: This timeout also includes the data communication between Envoy and the security processor.
            ## Optional: When the body processing is enabled, the timeout should be adjusted to accommodate
            ## the additional possible processing time. Larger payloads will require a longer timeout. 
            #message_timeout: 200ms

            ## Optional: Enable asynchronous mode analysis. Default is false.
            ## This mode will disable all blocking capabilities. The security processor should also be
            ## configured with the DD_SERVICE_EXTENSION_OBSERVABILITY_MODE environment variable.
            ## Beware, there is no flow control implemented in Envoy
            ## (cf https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/ext_proc.proto#envoy-v3-api-field-extensions-filters-http-ext-proc-v3-externalprocessor-observability-mode)
            #observability_mode: true
            ## Optional: When in asynchronous mode, the message_timeout is not used. This deferred
            ## timeout starts when the http request is finished, to let the security processor
            ## process all processing messages. Default is 5s.
            #deferred_close_timeout: 5s


    # Patch to add the Cluster definition for the Datadog External Processing service
    - applyTo: CLUSTER
      match:
        context: SIDECAR_INBOUND
        cluster:
          service: "*"
      patch:
        operation: ADD
        value:
          name: "datadog_aap_ext_proc_cluster" # A unique name for this cluster configuration
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          http2_protocol_options: {}
          transport_socket:
            name: envoy.transport_sockets.tls
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
              sni: "localhost"
          load_assignment:
            cluster_name: "datadog_aap_ext_proc_cluster"
            endpoints:
            - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      # Address of the Datadog security processor service
                      address: "datadog-aap-extproc-service.<your-preferred-namespace>.svc.cluster.local" # Adjust if your service name or namespace is different
                      port_value: 443
```

{% /tab %}

After you apply the `EnvoyFilter`, the Datadog security processor starts handling traffic through your Istio Ingress Gateway or selected sidecars.

### Step 3: Validate{% #step-3-validate %}

After this configuration is complete, the library collects security data from your application and sends it to the Agent. The Agent sends the data to Datadog, where [out-of-the-box detection rules](https://docs.datadoghq.com/security/default_rules.md#cat-application-security) flag attacker techniques and potential misconfigurations so you can take steps to remediate.

1. To see App and API Protection threat detection in action, send known attack patterns to your application. For example, trigger the [Security Scanner Detected](https://docs.datadoghq.com/security/default_rules/security-scan-detected.md) rule by running a file that contains the following curl script:

   ```
   for ((i=1;i<=250;i++)); do# Target existing service's routescurl https://your-application-url/existing-route -A dd-test-scanner-log;# Target non existing service's routescurl https://your-application-url/non-existing-route -A dd-test-scanner-log;done
```

**Note**: The `dd-test-scanner-log` value is supported in the most recent releases.

A few minutes after you enable your application and send known attack patterns to it, threat information appears in the [Application Signals Explorer](https://app.datadoghq.com/security/appsec) and vulnerability information appears in the [Vulnerabilities explorer](https://app.datadoghq.com/security/appsec/vm/).

{% video
   url="https://docs.dd-static.net/images//security/application_security/appsec-getstarted-threat-and-vuln_2.mp4" /%}

## Limitations{% #limitations %}

Known limitations:

- Inspection of request and response bodies is supported when using the Datadog security processor image version `v2.2.2` or later.

For additional details on the Istio integration compatibilities, see the [Istio integration compatibility page](https://docs.datadoghq.com/security/application_security/setup/compatibility/istio.md).

## Further Reading{% #further-reading %}

- [Envoy integration's source code](https://github.com/DataDog/dd-trace-go/tree/main/contrib/envoyproxy/go-control-plane/cmd/serviceextensions)
- [OOTB App and API Protection Rules](https://docs.datadoghq.com/security/default_rules.md?category=cat-application-security)
- [Troubleshooting App and API Protection](https://docs.datadoghq.com/security/application_security/troubleshooting.md)
