---
title: App and API Protection for Kubernetes
description: >-
  Automatically enable App and API Protection for your Kubernetes ingress
  proxies and gateways
breadcrumbs: Docs > Containers > Kubernetes > App and API Protection for Kubernetes
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# App and API Protection for Kubernetes

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

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

{% /callout %}

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

App and API Protection for Kubernetes automatically configures supported Kubernetes ingress proxies and gateways. Try it today!

[JOIN THE PREVIEW](https://www.datadoghq.com/product-preview/kubernetes-gateway-security-injector/)
{% /callout %}

This page describes how to set up [App and API Protection](https://docs.datadoghq.com/security/application_security.md) for Kubernetes to automatically configure supported Kubernetes ingress proxies and gateways to run API discovery, threat detection, and inline blocking at the edge of the infrastructure.

## Overview{% #overview %}

App and API Protection for Kubernetes automatically configures supported ingress proxies and gateways in your Kubernetes cluster to enable Application Security monitoring. This eliminates the need for manual proxy configuration and provides API-wide security coverage without modifying individual services or deploying tracers across your application fleet.

### What performs the automatic configuration?{% #what-performs-the-automatic-configuration %}

App and API Protection for Kubernetes uses a Kubernetes controller (running in the Datadog Cluster Agent) that:

- **Automatically detects** supported proxies in your cluster
- **Configures proxies** to route traffic through an external Application Security processor
- **Enables threat detection** for all traffic passing through your ingress layer
- **Simplifies operations** through centralized configuration with Helm

### Supported proxies{% #supported-proxies %}

For the list of supported proxies and proxy-specific setup steps, see the [setup page](https://docs.datadoghq.com/security/application_security/setup/kubernetes.md).

## Limitations{% #limitations %}

### Sidecar mode{% #sidecar-mode %}

- Requires Datadog Cluster Agent 7.80.2 or later
- Each gateway pod runs its own processor instance, which increases per-pod resource usage

### External mode{% #external-mode %}

- Requires Datadog Cluster Agent 7.80.2 or later
- Security processor must be manually deployed and scaled
- Deployed service may require an appropriate network policy:
  - From the proxy pods on the service port
  - To the Datadog Agent for traces

### Proxy compatibility{% #proxy-compatibility %}

- For proxy version compatibility, see the [compatibility documentation](https://docs.datadoghq.com/security/application_security/setup/compatibility.md).

## Prerequisites{% #prerequisites %}

Before enabling App and API Protection for Kubernetes, verify that you have:

- A running Kubernetes cluster (version 1.20 or later)
- [Datadog Cluster Agent 7.80.2 or later](https://docs.datadoghq.com/containers/kubernetes/installation.md) installed and configured in your cluster
- One or more [supported proxies](https://docs.datadoghq.com/security/application_security/setup/kubernetes.md) installed
- [Remote Configuration](https://docs.datadoghq.com/agent/remote_config.md?tab=helm#enabling-remote-configuration) enabled to allow blocking attackers through the Datadog UI

## How it works{% #how-it-works %}

App and API Protection for Kubernetes supports two deployment modes:

- **Sidecar mode** (default): The Application Security processor runs as a sidecar container injected directly into each gateway pod. No separate processor deployment is needed, and the processor scales automatically with your gateway pods.
- **External mode**: A single, centralized Application Security processor deployment serves all gateway traffic in your cluster. Use this mode when you want to manage one shared processor for the whole cluster.

To set up the default sidecar mode, see Set up sidecar mode. To deploy a centralized processor instead, see Set up external mode.

## Set up sidecar mode{% #set-up-sidecar-mode %}

In sidecar mode, the security processor runs as a container injected directly into each gateway pod. The Cluster Agent handles injection automatically, so you don't need a separate processor deployment or service.

### When to use sidecar mode{% #when-to-use-sidecar-mode %}

- You prefer not to manage a separate processor deployment and service
- You want the processor co-located with each gateway pod

### Setup{% #setup %}

{% tab title="Helm" %}
Add the following to your `values.yaml`. No `processor.service.*` values are needed because the injector handles processor deployment automatically.

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

Install or upgrade the Datadog Helm chart (version 3.153 or later):

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

{% /tab %}

{% tab title="Datadog Operator" %}
This option requires Datadog Operator version 1.27.1 or later.

Add annotations to your `DatadogAgent` resource. Sidecar mode is the default, so enabling the injector is enough:

```yaml
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
  annotations:
    agent.datadoghq.com/appsec.injector.enabled: "true"
```

Apply the configuration:

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

{% /tab %}

### Sidecar configuration reference{% #sidecar-configuration-reference %}

All sidecar parameters are available as Helm values nested under `datadog.appsec.injector.sidecar`, or as `DatadogAgent` annotations (Datadog Operator version 1.27.1 or later):

{% dl %}

{% dt %}
`sidecar.image`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.image`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `ghcr.io/datadog/dd-trace-go/service-extensions-callout`
{% /dd %}

{% dd %}
**Description**: Sidecar container image
{% /dd %}

{% dt %}
`sidecar.imageTag`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.image_tag`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `v2.6.0`
{% /dd %}

{% dd %}
**Description**: Sidecar container image tag
{% /dd %}

{% dt %}
`sidecar.port`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.port`
{% /dd %}

{% dd %}
**Type**: Integer
{% /dd %}

{% dd %}
**Default**: `8080`
{% /dd %}

{% dd %}
**Description**: gRPC listening port for the sidecar processor
{% /dd %}

{% dt %}
`sidecar.healthPort`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.health_port`
{% /dd %}

{% dd %}
**Type**: Integer
{% /dd %}

{% dd %}
**Default**: `8081`
{% /dd %}

{% dd %}
**Description**: Health check port for the sidecar processor
{% /dd %}

{% dt %}
`sidecar.bodyParsingSizeLimit`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.body_parsing_size_limit`
{% /dd %}

{% dd %}
**Type**: Integer
{% /dd %}

{% dd %}
**Default**: `0`
{% /dd %}

{% dd %}
**Description**: Maximum request body size in bytes to process. `0` disables body processing. Use `-1` to disable body parsing entirely.
{% /dd %}

{% dt %}
`sidecar.resources.requests.cpu`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.resources.requests.cpu`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `10m`
{% /dd %}

{% dd %}
**Description**: CPU request for the sidecar container
{% /dd %}

{% dt %}
`sidecar.resources.requests.memory`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.resources.requests.memory`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `128Mi`
{% /dd %}

{% dd %}
**Description**: Memory request for the sidecar container
{% /dd %}

{% dt %}
`sidecar.resources.limits.cpu`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.resources.limits.cpu`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `""`
{% /dd %}

{% dd %}
**Description**: CPU limit for the sidecar container (optional)
{% /dd %}

{% dt %}
`sidecar.resources.limits.memory`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.sidecar.resources.limits.memory`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `""`
{% /dd %}

{% dd %}
**Description**: Memory limit for the sidecar container (optional)
{% /dd %}

{% /dl %}

## Set up external mode{% #set-up-external-mode %}

In external mode, you deploy a single, centralized Application Security processor that serves all gateway traffic in your cluster. The Cluster Agent automatically configures your supported proxies to route traffic to this processor.

### Architecture{% #architecture %}

- **Security Processor Deployment**: You deploy a centralized Application Security processor as a Kubernetes Deployment with an associated Service.
- **Automatic Proxy Detection**: The controller watches for supported proxy resources in your cluster using Kubernetes informers.
- **Automatic Configuration**: When proxies are detected, the controller creates the proxy configuration needed to route traffic to the security processor service.
- **Traffic Processing**: Gateways route traffic to the security processor through the Kubernetes service for security analysis.

### Benefits{% #benefits %}

- **Resource Efficient**: A single shared processor handles traffic from all gateways
- **Centralized Management**: One deployment to monitor, scale, and configure
- **Infrastructure-as-Code**: Manage configuration through Helm values
- **Non-Invasive**: No application code changes required
- **Scalable**: Add new gateways without additional configuration

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

Deploy the security processor service, which analyzes traffic forwarded from your gateways. For proxy-specific deployment details, see the [setup documentation](https://docs.datadoghq.com/security/application_security/setup/kubernetes.md) for your proxy.

Example deployment:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: datadog-aap-extproc-deployment
  namespace: datadog
spec:
  replicas: 2
  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.4.0
        ports:
        - name: grpc
          containerPort: 443
        - name: health
          containerPort: 80
        env:
        # Use the address of the datadog agent service in your cluster
        - name: DD_AGENT_HOST
          value: "datadog-agent.datadog.svc.cluster.local"

        - name: DD_SERVICE_EXTENSION_TLS
          value: "false"
        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
  namespace: datadog
spec:
  ports:
  - name: grpc
    port: 443
    targetPort: grpc
  selector:
    app: datadog-aap-extproc
  type: ClusterIP
```

Apply the manifest:

```bash
kubectl apply -f datadog-aap-extproc-service.yaml
```

### Step 2: Enable automatic configuration{% #step-2-enable-automatic-configuration %}

Point the Datadog Cluster Agent at your security processor service using Helm or the Datadog Operator.

**Note:** The processor service name (`datadog-aap-extproc-service`) must match the service you deployed in Step 1.

{% tab title="Datadog Operator" %}
This option requires Datadog Operator version 1.27.1 or later.

Add annotations to your `DatadogAgent` resource. The service name annotation is required and must match your security processor service:

```yaml
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
  annotations:
    agent.datadoghq.com/appsec.injector.enabled: "true"
    agent.datadoghq.com/appsec.injector.mode: "external"
    agent.datadoghq.com/appsec.injector.processor.service.name: "datadog-aap-extproc-service"  # Required: must match your security processor service name
    agent.datadoghq.com/appsec.injector.processor.service.namespace: "datadog"
```

Apply the configuration:

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

{% /tab %}

{% tab title="Helm" %}
Configure App and API Protection for Kubernetes using Helm values. Add the following to your `values.yaml`:

```yaml
datadog:
  appsec:
    injector:
      enabled: true
      mode: "external"
      processor:
        service:
          name: datadog-aap-extproc-service  # Required: must match your security processor service name
          namespace: datadog                 # Must match the namespace where the service is deployed
```

Install or upgrade the Datadog Helm chart (version 3.153 or later):

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

{% /tab %}

### Step 3: Verify the installation{% #step-3-verify-the-installation %}

Check that the Cluster Agent detected your proxies:

```bash
kubectl logs -n datadog deployment/datadog-cluster-agent | grep appsec
```

#### Verify proxy configuration{% #verify-proxy-configuration %}

Verify that the controller created the proxy configuration resources for your proxy. For proxy-specific verification commands, see the [setup documentation](https://docs.datadoghq.com/security/application_security/setup/kubernetes.md) for your proxy.

The Datadog Cluster Agent produces events for each operation that results in failure or success done in the cluster.

#### Test traffic processing{% #test-traffic-processing %}

Send requests through your gateway and verify they appear in the Datadog [App and API Protection](https://app.datadoghq.com/security/appsec) UI:

1. Navigate to [Security > Application Security](https://app.datadoghq.com/security/appsec) in Datadog.
1. Look for security signals from your gateway traffic.
1. Verify that threat detection is active.

## Configuration reference{% #configuration-reference %}

### Automatic configuration options{% #automatic-configuration-options %}

{% dl %}

{% dt %}
`enabled`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.enabled`
{% /dd %}

{% dd %}
**Type**: Boolean
{% /dd %}

{% dd %}
**Default**: `false`
{% /dd %}

{% dd %}
**Description**: Enable or disable the integration
{% /dd %}

{% dt %}
`mode`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.mode`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `""`; when empty, defaults to sidecar
{% /dd %}

{% dd %}
**Description**: Injection mode: `"sidecar"` or `"external"`
{% /dd %}

{% dt %}
`autoDetect`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.autoDetect`
{% /dd %}

{% dd %}
**Type**: Boolean
{% /dd %}

{% dd %}
**Default**: `true`
{% /dd %}

{% dd %}
**Description**: Automatically detect and configure supported proxies
{% /dd %}

{% dt %}
`proxies`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.proxies`
{% /dd %}

{% dd %}
**Type**: JSON array
{% /dd %}

{% dd %}
**Default**: `[]`
{% /dd %}

{% dd %}
**Description**: Manual list of proxy types to configure. For valid values, see the [setup page](https://docs.datadoghq.com/security/application_security/setup/kubernetes.md).
{% /dd %}

{% dt %}
`processor.service.name`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.processor.service.name`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: None
{% /dd %}

{% dd %}
**Description**: **Required.** Name of the security processor Kubernetes Service
{% /dd %}

{% dt %}
`processor.service.namespace`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.processor.service.namespace`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: Defaults to the namespace where the Cluster Agent is running
{% /dd %}

{% dd %}
**Description**: Namespace where the security processor service is deployed
{% /dd %}

{% dt %}
`processor.address`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.processor.address`
{% /dd %}

{% dd %}
**Type**: String
{% /dd %}

{% dd %}
**Default**: `{service.name}.{service.namespace}.svc`
{% /dd %}

{% dd %}
**Description**: Full service address override
{% /dd %}

{% dt %}
`processor.port`
{% /dt %}

{% dd %}
**Datadog Operator annotation**: `agent.datadoghq.com/appsec.injector.processor.port`
{% /dd %}

{% dd %}
**Type**: Integer
{% /dd %}

{% dd %}
**Default**: `443`
{% /dd %}

{% dd %}
**Description**: Port of the security processor service
{% /dd %}

{% /dl %}

### Upgrading from external mode{% #upgrading-from-external-mode %}

If you are upgrading from a previous version that used external mode, the default mode has changed to sidecar. To continue using external mode, explicitly set `mode: "external"` in your Helm values:

```yaml
datadog:
  appsec:
    injector:
      enabled: true
      mode: "external"
      processor:
        service:
          name: datadog-aap-extproc-service
          namespace: datadog
```

### Opting out specific resources{% #opting-out-specific-resources %}

You can exclude specific Gateway or GatewayClass resources from automatic configuration by adding a label:

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
  namespace: my-namespace
  labels:
    appsec.datadoghq.com/enabled: "false"  # Exclude this gateway from automatic configuration
spec:
  # ... gateway configuration
```

Resources with the `appsec.datadoghq.com/enabled: "false"` label are ignored. This is useful when you want to:

- Manually configure specific gateways
- Temporarily disable App and API Protection for testing
- Exclude certain gateways from security monitoring

**Note**: By default, all resources are included. Only resources with the label explicitly set to `"false"` are excluded.

## Troubleshooting{% #troubleshooting %}

All errors are logged as Kubernetes events. Check for events on the Gateway or GatewayClass you want to instrument.

### Automatic configuration not detecting proxies{% #automatic-configuration-not-detecting-proxies %}

**Symptom**: No proxy configuration resources are created.

**Solutions**:

- Check that `autoDetect` is set to `true` or proxies are manually specified
- Verify the Cluster Agent logs for proxy detection messages
- Verify that your proxies are installed and have the expected Kubernetes resources (Gateway, GatewayClass)
- Try manually specifying proxy types using the `proxies` parameter

### Proxy configuration not created{% #proxy-configuration-not-created %}

**Symptom**: The controller is running but configuration resources are missing.

**Solutions**:

- Check Cluster Agent logs for RBAC permission errors
- Verify the Cluster Agent service account has permissions to create the proxy configuration resources
- Verify that the processor service exists and is accessible
- Check for conflicting existing policies or filters

### Traffic not being processed{% #traffic-not-being-processed %}

**Symptom**: No security events appear in the Datadog UI.

**Solutions**:

- Verify the security processor deployment is running: `kubectl get pods -n datadog -l app=datadog-aap-extproc`
- Look for warning logs in your reverse proxies concerning this part of the configuration.
- Check processor logs for connection errors: `kubectl logs -n datadog -l app=datadog-aap-extproc`
- Verify the processor service is correctly configured and resolvable
- Test connectivity from gateway pods to the processor service
- Verify that [Remote Configuration](https://docs.datadoghq.com/agent/remote_config.md?tab=helm#enabling-remote-configuration) is enabled in your Datadog Agent

### Security processor connection issues{% #security-processor-connection-issues %}

**Symptom**: Gateways cannot reach the security processor.

**Solutions**:

- Verify the processor service name and namespace match your configuration
- Check for NetworkPolicy rules blocking cross-namespace traffic
- Test DNS resolution from gateway pods: `nslookup datadog-aap-extproc-service.datadog.svc.cluster.local`
- Verify the processor port configuration matches the service definition

### RBAC permission errors{% #rbac-permission-errors %}

**Symptom**: Cluster Agent logs show permission denied errors.

**Solutions**:

- Verify the Cluster Agent ClusterRole includes permissions for:
  - `gateway.networking.k8s.io/gateways`
  - `gateway.networking.k8s.io/gatewayclasses`
- Check that the ClusterRoleBinding references the correct service account
- Make sure you are using the newest version of the Datadog Helm Chart or Operator.

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

- [Collect your application traces](https://docs.datadoghq.com/containers/kubernetes/apm.md)
- [Collect your application logs](https://docs.datadoghq.com/containers/kubernetes/log.md)
- [App and API Protection for Envoy Gateway](https://docs.datadoghq.com/security/application_security/setup/kubernetes/envoy-gateway.md)
- [App and API Protection for Istio](https://docs.datadoghq.com/security/application_security/setup/kubernetes/istio.md)
- [App and API Protection for ingress-nginx](https://docs.datadoghq.com/security/application_security/setup/nginx/ingress-controller.md)
- [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)
