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

# Send Kubernetes audit logs

> Send Kubernetes API audit logs from Amazon EKS, Google Kubernetes Engine, or a self-managed cluster to Sazabi, so you can see who exec'd into pods, read secrets, or changed RBAC.

Kubernetes audit logs record every request to the Kubernetes API server: who made it, which verb and resource it touched, and whether it was allowed. They show who exec'd into a pod, read a secret, or changed a role binding. There is no separate Kubernetes log source: audit logs arrive through the log source your platform already uses. On Amazon EKS that is AWS CloudWatch, on Google Kubernetes Engine (GKE) it is Google Cloud, and on a self-managed cluster it is the OpenTelemetry Collector. Pick the section for your cluster.

## Send EKS audit logs

**Recommended when:** your cluster runs on Amazon EKS.

EKS writes control-plane logs to the CloudWatch log group `/aws/eks/<cluster name>/cluster`. Audit events are in the log streams named `kube-apiserver-audit-<id>`.

**Step 1**

Turn on the `audit` control-plane log type for the cluster. In the AWS console, open the cluster's **Observability** tab and choose **Manage logging** under **Control plane logging**, or run:

```bash theme={"system"}
aws eks update-cluster-config \
  --region us-east-1 \
  --name my-cluster \
  --logging '{"clusterLogging":[{"types":["audit"],"enabled":true}]}'
```

Replace the region and cluster name with your own. Control-plane log types you already turned on stay on.

**Step 2**

Connect the [AWS CloudWatch](https://docs.sazabi.com/catalogs/log-sources/connect-your-account/cloudwatch.md) log source to the cluster's AWS account, in a Sazabi project in the cluster's region. To limit Sazabi's role to EKS log groups when you create it with CloudFormation, set the stack's `AllowedLogGroupPrefix` parameter to `/aws/eks/`.

**Step 3**

Open the CloudWatch log source in [**Settings > Log streams**](https://app.sazabi.com/settings/log-source-providers), click **Add log stream**, and select `/aws/eks/<cluster name>/cluster`.

> [!NOTE]
>
> CloudWatch allows at most two subscription filters per log group, and Sazabi uses one. AWS bills CloudWatch ingestion and storage for control-plane logs; audit is the highest-volume type. AWS sets the EKS audit policy, so you cannot change which requests it records.

## Send GKE audit logs

**Recommended when:** your cluster runs on Google Kubernetes Engine.

GKE writes Kubernetes audit logs to Cloud Audit Logs in the cluster's project, with the service name `k8s.io` and the resource type `k8s_cluster`. Admin Activity audit logs (writes such as creating a pod, `pods/exec`, and RBAC changes) are always on. Data Access audit logs (reads such as `get secrets`) are off by default.

**Step 1**

Connect the [Google Cloud](https://docs.sazabi.com/catalogs/log-sources/connect-your-account/gcp.md) log source and add a log stream for the cluster's GCP project. The sink Sazabi creates forwards every log entry in the project, Cloud Audit Logs included, so Admin Activity audit logs arrive with no extra setup.

If you send to an endpoint instead, use this filter on the [Google Cloud (send to an endpoint)](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/gcp.md) sink to forward only Kubernetes audit logs:

```txt theme={"system"}
logName:"cloudaudit.googleapis.com" AND resource.type="k8s_cluster"
```

**Step 2**

Optional: to record reads, turn on Data Access audit logs. In the Google Cloud console, open **IAM & Admin > Audit Logs**, select **Kubernetes Engine API**, check **Data Read** and **Data Write**, and save. Data Access logs are high volume, and Cloud Logging and Pub/Sub bill for them.

## Send self-managed cluster audit logs

**Recommended when:** you run the Kubernetes control plane yourself (kubeadm, k3s, or similar).

The API server writes audit events as JSON lines to a file, and an OpenTelemetry Collector on each control-plane node reads that file and sends it to Sazabi.

**Step 1**

Write an audit policy. This one records request metadata for every request, which covers exec, secret reads, and RBAC changes without storing request bodies:

```yaml title="/etc/kubernetes/audit-policy.yaml" theme={"system"}
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - RequestReceived
rules:
  - level: Metadata
```

**Step 2**

Start `kube-apiserver` with the log backend turned on:

```bash theme={"system"}
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit/audit.log
--audit-log-maxage=7
--audit-log-maxbackup=5
--audit-log-maxsize=100
```

If the API server runs as a static pod, mount the policy file and the log directory into it.

**Step 3**

Add the [OpenTelemetry Collector](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/otel-collector.md) log source and copy its **Intake URL**. Run a Collector on each control-plane node that reads the audit log:

```yaml title="otelcol.yaml" theme={"system"}
receivers:
  filelog/k8s-audit:
    include: [/var/log/kubernetes/audit/*.log]
    start_at: end

exporters:
  otlphttp/sazabi:
    endpoint: <your intake URL>

service:
  pipelines:
    logs:
      receivers: [filelog/k8s-audit]
      exporters: [otlphttp/sazabi]
```

Replace `<your intake URL>` with the intake URL you copied. Fluent Bit works too: point a `tail` input at the same path and send to the [Fluent Bit](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/fluent-bit.md) log source.

## Verify

Confirm an audit event reaches your project.

1. Make a write request against the cluster, which every audit setup above records (GKE Admin Activity logs included): `kubectl create configmap sazabi-audit-check -n default`. Delete it afterwards with `kubectl delete configmap sazabi-audit-check -n default`.
2. In a thread, ask the Sazabi agent for Kubernetes audit events from the last 15 minutes, or run `sazabi logs ask "kubernetes audit events that created the sazabi-audit-check configmap in the last 15 minutes"`.
3. You should see an event with verb `create`, resource `configmaps`, your user name, and response code `201`. On GKE the method is `io.k8s.core.v1.configmaps.create`. EKS and GKE deliver audit events within a few minutes; a self-managed Collector delivers them within a minute.

If nothing appears, confirm the audit log type is on (EKS), the log stream for the cluster's project exists (GKE), or the Collector can read the audit log file (self-managed).

## Further reading

> [card] [AWS CloudWatch](https://docs.sazabi.com/catalogs/log-sources/connect-your-account/cloudwatch.md)
>
> Connect your AWS account and pick log groups.

> [card] [Google Cloud](https://docs.sazabi.com/catalogs/log-sources/connect-your-account/gcp.md)
>
> Connect your Google Cloud account and pick projects.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.