# Argo CD Audit Log: A Complete Guide to Kubernetes Event Tracking

> Understand the Argo CD audit log for Kubernetes event tracking. Discover who did what, to which resource, and why with this complete guide.

- Repository: [Argo Project/argo-cd](https://github.com/argoproj/argo-cd)
- Tags: deep-dive
- Published: 2026-07-09

---

**Argo CD records operational activity as native Kubernetes Events through an internal `AuditLogger` that captures who performed an action, what resource was affected, and why it occurred.**

The Argo CD audit log provides a critical security and observability layer for GitOps workflows. As implemented in the `argoproj/argo-cd` repository, this mechanism emits Kubernetes Events to track user actions and system operations, complementing the immutable Git commit history with a view of what was actually applied to the cluster.

## How the Argo CD Audit Logger Works

The audit logging system centers on the `AuditLogger` struct in [`util/argo/audit_logger.go`](https://github.com/argoproj/argo-cd/blob/main/util/argo/audit_logger.go). This component filters, constructs, and persists operational events through six distinct phases:

1. **AuditLogger Creation** – When the server, application controller, or ApplicationSet controller starts, it invokes `argo.NewAuditLogger`. This function receives a Kubernetes client, the Argo CD namespace, the component name (e.g., `argocd-server`), and a list of event reasons to enable (`enableK8sEvent`). The enabled reasons are stored in a map (`enableEventLog`) for fast lookup.

2. **Event Filtering** – Before emitting an event, the logger checks `enableK8sEventLog(info)` (lines 15‑18 in [`audit_logger.go`](https://github.com/argoproj/argo-cd/blob/main/audit_logger.go)). If the event's `Reason` is not in the enabled list, nothing is logged. By default, `DefaultEnableEventList` returns `["all"]`, enabling every reason.

3. **Event Construction** – The `logEvent` method builds a `corev1.Event` structure (lines 49‑106) containing:
   - **Standard fields** – `type`, `reason`, `message`, timestamps, and count
   - **Object reference** – Target resource's `Kind`, `Name`, `Namespace`, `UID`, and API version
   - **Annotations** – Acting `user`, destination server/namespace, and for non‑Application resources, the original namespace (`resource‑namespace`)

4. **Event Destination** – For Application‑level events (Application, AppProject, ApplicationSet), the event is created in the resource's own namespace. For generic resources, the event is created in the Argo CD namespace to support multi‑cluster deployments (lines 68‑75).

5. **Persistence** – The event is written to the Kubernetes API via `l.kIf.CoreV1().Events(eventNamespace).Create`. Operators can retain these events longer than the cluster's default TTL using tools like **Event Exporter** or **Event Router** (documented in [`security.md`](https://github.com/argoproj/argo-cd/blob/main/security.md) lines 100‑102).

6. **Visibility** – Users can view audit events with `kubectl get events`. The events include the `source.component` (e.g., `argocd-server`) and a human‑readable message, making it easy to trace actions back to a specific user or automation token (see example output in [`security.md`](https://github.com/argoproj/argo-cd/blob/main/security.md) lines 84‑98).

## Where the Audit Log is Used in the Codebase

The `AuditLogger` is integrated across multiple controllers and servers to ensure comprehensive coverage:

- **Application Controller** – [`controller/appcontroller.go`](https://github.com/argoproj/argo-cd/blob/main/controller/appcontroller.go) creates an `AuditLogger` and logs sync operations via `LogAppEvent`.
- **Application API Server** – [`server/application/application.go`](https://github.com/argoproj/argo-cd/blob/main/server/application/application.go) uses the logger for CRUD operations on Applications, ApplicationSets, and individual resources.
- **Project Controller** – [`server/project/project.go`](https://github.com/argoproj/argo-cd/blob/main/server/project/project.go) logs project‑level changes via `LogAppProjEvent`.

These calls funnel through the same `AuditLogger` implementation, ensuring consistent audit format across the entire stack.

## Practical Implementation Examples

### Creating an AuditLogger

During server initialization, components instantiate the logger with specific configuration:

```go
import (
    "github.com/argoproj/argo-cd/util/argo"
    "k8s.io/client-go/kubernetes"
)

// kubeClient – a Kubernetes client‑go interface
// ns – the namespace where Argo CD is installed
// component – e.g. "argocd-server"
// enableK8sEvent – list of event reasons to enable (empty = default all)

auditLogger := argo.NewAuditLogger(kubeClient, ns, component, enableK8sEvent)

```

### Logging an Application Event

To record a sync operation:

```go
eventInfo := argo.EventInfo{
    Type:   "Normal",
    Reason: argo.EventReasonOperationStarted,
}
message := "admin initiated sync to HEAD (abc123)"
user := "admin@example.com"

auditLogger.LogAppEvent(myApp, eventInfo, message, user, nil)

```

This generates a Kubernetes Event resembling: `guestbook.157f7c5f0f747acf   Application   Normal   OperationStarted   argocd-server   admin initiated sync to HEAD (abc123)`.

### Enabling Selective Event Logging

Filter events to reduce noise:

```go
// Only log sync‑related events
auditLogger := argo.NewAuditLogger(kubeClient, ns, component, []string{
    argo.EventReasonOperationStarted,
    argo.EventReasonOperationCompleted,
})

```

### Exporting Audit Events for Long‑Term Retention

Since Kubernetes events have a short TTL, export them for persistence:

```bash

# Example: forward all Argo CD events to a Google Cloud Pub/Sub topic

kubectl apply -f https://github.com/GoogleCloudPlatform/k8s-stackdriver/tree/master/event-exporter

```

See [`docs/operator-manual/security.md`](https://github.com/argoproj/argo-cd/blob/main/docs/operator-manual/security.md) lines 100‑102 for additional export strategies.

## Key Source Files

Understanding the audit log requires familiarity with these specific files in the `argoproj/argo-cd` repository:

- **[`util/argo/audit_logger.go`](https://github.com/argoproj/argo-cd/blob/main/util/argo/audit_logger.go)** – Contains the core `AuditLogger` struct, `NewAuditLogger` constructor, and `logEvent` implementation (lines 49‑106).
- **[`controller/appcontroller.go`](https://github.com/argoproj/argo-cd/blob/main/controller/appcontroller.go)** – Instantiates the logger for the application controller and invokes `LogAppEvent` during sync operations.
- **[`server/application/application.go`](https://github.com/argoproj/argo-cd/blob/main/server/application/application.go)** – Handles CRUD logging for Applications, ApplicationSets, and individual resources.
- **[`server/project/project.go`](https://github.com/argoproj/argo-cd/blob/main/server/project/project.go)** – Logs project‑level changes via `LogAppProjEvent`.
- **[`docs/operator-manual/security.md`](https://github.com/argoproj/argo-cd/blob/main/docs/operator-manual/security.md)** – Documents the audit log concept, sample `kubectl get events` output, and export options (lines 84‑102).

## Summary

- **Argo CD audit logs** are implemented as native Kubernetes Events, not external log files.
- The **`AuditLogger`** in [`util/argo/audit_logger.go`](https://github.com/argoproj/argo-cd/blob/main/util/argo/audit_logger.go) filters events by reason and constructs detailed event objects with user annotations.
- Events for Applications, AppProjects, and ApplicationSets are stored in their respective namespaces, while generic resource events go to the Argo CD namespace to support multi‑cluster deployments.
- **`LogAppEvent`** and **`LogAppProjEvent`** are the primary methods used across controllers to emit audit events.
- Events persist only for the cluster's default TTL unless exported using tools like **Event Exporter** or **Event Router**.
- Query logs using standard `kubectl get events` commands, filtering by `source.component` (e.g., `argocd-server`).

## Frequently Asked Questions

### What is the Argo CD audit log?

The Argo CD audit log is a security feature that records operational activity as Kubernetes Events. It tracks who performed GitOps actions, what resources were modified, and why changes occurred, providing a searchable trail that complements the immutable Git history.

### How do I view Argo CD audit logs?

You can view audit logs using standard Kubernetes tooling: `kubectl get events --namespace argocd` or `kubectl get events --namespace <app-namespace>`. The events include the component name in `source.component` (e.g., `argocd-server`) and a message field describing the action, allowing you to trace specific user or token activity.

### How long are Argo CD audit events retained?

By default, Kubernetes events have a short TTL (typically 1 hour to 1 hour and 15 minutes depending on the cluster configuration). For long‑term retention, you must export events using tools like the **Kubernetes Event Exporter** or **Event Router** to external systems such as Elasticsearch, Cloud Pub/Sub, or Splunk.

### Can I filter which events are logged?

Yes. When creating an `AuditLogger` via `NewAuditLogger`, you can pass a slice of enabled reasons (e.g., `EventReasonOperationStarted`, `EventReasonOperationCompleted`). If you pass an empty list or `["all"]`, the logger emits events for all reasons. This filtering occurs in the `enableK8sEventLog` function (lines 15‑18 of [`audit_logger.go`](https://github.com/argoproj/argo-cd/blob/main/audit_logger.go)).