Argo CD Audit Log: A Complete Guide to Kubernetes Event Tracking
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. This component filters, constructs, and persists operational events through six distinct phases:
-
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. -
Event Filtering – Before emitting an event, the logger checks
enableK8sEventLog(info)(lines 15‑18 inaudit_logger.go). If the event'sReasonis not in the enabled list, nothing is logged. By default,DefaultEnableEventListreturns["all"], enabling every reason. -
Event Construction – The
logEventmethod builds acorev1.Eventstructure (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)
- Standard fields –
-
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).
-
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 insecurity.mdlines 100‑102). -
Visibility – Users can view audit events with
kubectl get events. The events include thesource.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 insecurity.mdlines 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.gocreates anAuditLoggerand logs sync operations viaLogAppEvent. - Application API Server –
server/application/application.gouses the logger for CRUD operations on Applications, ApplicationSets, and individual resources. - Project Controller –
server/project/project.gologs project‑level changes viaLogAppProjEvent.
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:
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:
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:
// 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:
# 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 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– Contains the coreAuditLoggerstruct,NewAuditLoggerconstructor, andlogEventimplementation (lines 49‑106).controller/appcontroller.go– Instantiates the logger for the application controller and invokesLogAppEventduring sync operations.server/application/application.go– Handles CRUD logging for Applications, ApplicationSets, and individual resources.server/project/project.go– Logs project‑level changes viaLogAppProjEvent.docs/operator-manual/security.md– Documents the audit log concept, samplekubectl get eventsoutput, and export options (lines 84‑102).
Summary
- Argo CD audit logs are implemented as native Kubernetes Events, not external log files.
- The
AuditLoggerinutil/argo/audit_logger.gofilters 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.
LogAppEventandLogAppProjEventare 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 eventscommands, filtering bysource.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).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →