Agent Permissions & Security Posture
What the agent's Kubernetes ServiceAccount can do, what it can't, and why.
What the DataAgent agent’s Kubernetes ServiceAccount can do in your cluster, what it can’t, and why. Companion to the Agent Install Guide.
TL;DR
- Read-only on your workloads — the agent cannot create, modify, or delete any of your Deployments, Pods, Services, or configurations.
- Your secrets stay in your cluster on the default path — K8sGPT runs inside the agent pod, and the default analysis path does not send workload contents (Secrets, ConfigMaps, or other resource bodies) to the DataAgent platform.
- No AWS IAM, no cloud-provider access — the agent talks only to the DataAgent platform and to ghcr.io for image pulls. Nothing else.
- You can verify and lock down further — audit live permissions with the command below; disable analyzers or apply quotas to narrow the surface.
What the agent does NOT do
- Modify your workloads — no
create,update,delete, orpatchverbs on Deployments, Pods, Services, ConfigMaps, or any workload object. - Send workload contents (Secrets, ConfigMaps, or other resource bodies) to the DataAgent platform on the default analysis path. Default-mode analysis emits textual findings only; raw values are not forwarded.
- Require any AWS IAM role, IRSA, or EKS Pod Identity configuration.
- Reach into your cloud provider’s APIs — IAM, storage, networking, billing.
- Make any outbound connection other than
tunnel.data-agent.co:443(mTLS-authenticated) andghcr.io:443(image pulls). The bundled monitoring pods’ images are pulled fromquay.io,registry.k8s.io, anddocker.io— see Prerequisites → Network.
Verify the live permissions
helm template dataagent oci://ghcr.io/data-agent-co/dataagent-chart \
--version <CHART_VERSION> \
| grep -B2 -A40 'kind: ClusterRole\|kind: Role'The chart is public, so no helm registry login is needed. This command is the
authoritative list: it renders exactly the rules your install would create,
including the bundled monitoring’s.
The chart installs namespace-scoped Roles in the dataagent namespace and
several ClusterRoles. Most ClusterRoles belong to one container and are
removed when you disable it at install time. The sections below describe the
rules the chart’s defaults create; re-run the command above against the version
you install rather than relying on this page alone.
Why the agent reads Secrets and ConfigMaps
The default install gives the agent cluster-wide read access to Secrets and ConfigMaps. Here’s why, what the agent does with the contents, and how to narrow the surface if your posture requires it.
Why — failure diagnosis. The topology analyzer and the K8sGPT analysis it runs identify pods stuck on a missing or unreadable Secret, ConfigMaps with the wrong key mounted, or admission webhooks rejecting deployments. None of these diagnoses are possible without reading what’s mounted.
What the agent does with the contents:
- Reads only. There are no write verbs anywhere in the analyzer ClusterRoles.
- In-cluster processing. Values are scanned by K8sGPT inside the agent pod, never exported raw.
- The default analysis path does not forward workload contents. K8sGPT runs locally inside the agent pod, emitting textual findings (e.g. “Secret
db-credsmounted byapi-serveris missing keypassword”). The default path operates without the LLM backend, so the Secret’s value is not transmitted to the DataAgent platform — note this is a property of the default path, not an in-pod redaction boundary.
To remove cluster-wide Secret read, disable the topology analyzer:
--set topologyAnalyzer.enabled=falseK8sGPT analysis runs inside the topology analyzer, so this also turns off K8sGPT- and topology-based signals. The same ClusterRole also serves pod-log and Helm-release lookups during root-cause analysis (Helm stores releases as Secrets), so those lookups stop working too. The agent keeps running and still reports events, log errors, and metrics.
ConfigMaps are also read cluster-wide by the watcher (to report ConfigMap
changes), by the live-read service account (through the built-in view
role), and by the bundled Prometheus. To remove all cluster-wide ConfigMap read
as well, add --set watcher.enabled=false --set liveRead.enabled=false --set da-monitoring.enabled=false.
Namespace-scoped — dataagent namespace
| Resource | Verbs | Why |
|---|---|---|
secrets | create (any in the dataagent namespace) | Write the agent’s mTLS certificate Secret when it doesn’t already exist. The verb cannot be name-scoped because the object doesn’t exist at create time. |
secrets | get, update, delete on dataagent-mtls-credentials only | Read the agent’s own certificate on connect, update it on rotation, delete it on stale-credential cleanup. This Role grants no access to any other Secret in this namespace (the cluster-wide read below still applies). |
serviceaccounts/token | create on dataagent-live-read only | Request short-lived tokens for the agent’s separate, read-only live-read service account (see below). Created only when liveRead.enabled=true (the default). |
Cluster-scoped — always created
These rules are created whenever the chart’s rbac.create is true (the default),
independent of which analyzers are enabled. They let the agent look for a
Prometheus in the cluster when the bundled one is disabled. Only the bundled
Prometheus is a supported integration, but these rules are still created.
| Resource | Verbs | Why |
|---|---|---|
core/services | list | Scan well-known namespaces for a Prometheus Service when the Operator CRD isn’t present. |
apiextensions.k8s.io/customresourcedefinitions | get (cluster-wide on all CRDs) | Detect whether the Prometheus Operator is installed. Denied gracefully — the agent falls back to Service scan. The rule is not name-restricted; the chart grants get cluster-wide on all CRDs, but the agent only reads the prometheuses CRD by name. |
monitoring.coreos.com/prometheuses | list | When the Operator CRD is present, find Prometheus CR instances to derive the Service endpoint. |
The agent never writes any of the resources above, and it does not read Prometheus contents over the Kubernetes API — it talks plain HTTP to the discovered Service endpoint.
Cluster-scoped — metrics collector (optional)
Created only when metricsCollector.enabled=true (the default). Disable with
--set metricsCollector.enabled=false to remove every rule below.
| Resource | Verbs | Why |
|---|---|---|
core/pods, nodes, events | get, list | Resource inventory and event correlation for SRE golden signals (latency, errors, traffic, saturation). |
apps/deployments, statefulsets, daemonsets | get, list | Workload-level signal attribution — link metrics back to the controller that owns the pod. |
metrics.k8s.io/pods, nodes | get, list | Read CPU/memory utilisation from metrics-server. The agent fails gracefully if metrics-server is unavailable. |
Cluster-scoped — topology analyzer and K8sGPT analysis (optional)
Created when topologyAnalyzer.enabled=true (the default). K8sGPT analysis runs
inside the topology analyzer and reads through this role. See Why the agent
reads Secrets and ConfigMaps above for the rationale on the wider read scope.
| Resource | Verbs | Why |
|---|---|---|
core/pods, pods/log, pods/status, events, services, configmaps, secrets, persistentvolumeclaims, persistentvolumes, nodes, namespaces, serviceaccounts, resourcequotas, endpoints, limitranges | get, list, watch | Configuration objects K8sGPT reads to diagnose issues, plus pod-log and Helm-release (Secret) lookups during root-cause analysis. |
apps/deployments, replicasets, statefulsets, daemonsets | get, list, watch | Workload graph and status. |
batch/jobs, cronjobs | get, list, watch | Batch workload visibility. |
networking.k8s.io/ingresses, ingressclasses, networkpolicies | get, list, watch | Network topology and policy context. |
discovery.k8s.io/endpointslices | get, list, watch | Map Services to the pods behind them. |
storage.k8s.io/storageclasses | get, list, watch | Storage topology and PVC binding diagnosis. |
rbac.authorization.k8s.io/clusterroles, roles, clusterrolebindings, rolebindings | get, list, watch | Show which service accounts are bound to which roles in the topology. |
policy/poddisruptionbudgets | get, list, watch | PDB-related disruption diagnosis. |
autoscaling/horizontalpodautoscalers | get, list, watch | Scaling-decision context. |
apiextensions.k8s.io/customresourcedefinitions | get, list, watch | CRD discovery for topology mapping. |
cert-manager.io/certificates | get, list, watch | Certificate status and expiry, when cert-manager is installed. |
admissionregistration.k8s.io/mutatingwebhookconfigurations, validatingwebhookconfigurations | get, list, watch | K8sGPT analyzer reads webhook configuration to diagnose admission-related failures. |
Cluster-scoped — watcher (optional)
Created when watcher.enabled=true (the default).
| Resource | Verbs | Why |
|---|---|---|
core/events, configmaps | get, list, watch | Report Kubernetes Warning events and ConfigMap changes as they happen. |
Log watcher (optional)
Created when logWatcher.enabled=true (the default). With
logWatcher.config.namespaces empty (the default) this is a ClusterRole;
when you list namespaces, it becomes one Role per listed namespace instead.
Listing namespaces narrows what the log watcher reads, not what the agent is
allowed to read: the topology analyzer’s ClusterRole above grants pods/log
cluster-wide to the same service account. Cluster-wide pod-log read remains
unless you also set topologyAnalyzer.enabled=false.
| Resource | Verbs | Why |
|---|---|---|
core/pods | get, list, watch | Find the containers whose logs to read. |
core/pods/log | get | Read pod logs and match them against known error patterns. |
Cluster-scoped — live reads (optional)
Created when liveRead.enabled=true (the default). During root-cause analysis
the agent can look up the current state of individual objects. Those lookups
run as a separate dataagent-live-read service account bound to Kubernetes’
built-in view ClusterRole, not as the agent’s own account. view cannot
read Secrets, so the Kubernetes API server itself refuses a Secret lookup.
liveRead.extraReadRules adds read rules for custom resources that view
does not cover.
view does not include cluster-scoped objects, so the chart adds one more
ClusterRole for the live-read service account:
| Resource | Verbs | Why |
|---|---|---|
core/nodes, persistentvolumes | get, list | Look up the current state of nodes and volumes during an incident. |
Bundled monitoring (optional)
Created when da-monitoring.enabled=true (the default). These rules belong to
the monitoring pods’ own service accounts, not to the agent’s.
prometheus-server — scrapes infrastructure metrics:
| Resource | Verbs | Why |
|---|---|---|
core/nodes, nodes/metrics, services, endpoints, pods, ingresses, configmaps | get, list, watch | Discover scrape targets. |
networking.k8s.io/ingresses, ingresses/status | get, list, watch | Discover scrape targets. |
discovery.k8s.io/endpointslices | get, list, watch | Discover scrape targets. |
non-resource URL /metrics | get | Read the API server’s own metrics. |
kube-state-metrics — turns object state into metrics:
| Resource | Verbs | Why |
|---|---|---|
core/pods, endpoints, persistentvolumeclaims | list, watch | Pod, endpoint, and volume-claim state metrics. |
autoscaling/horizontalpodautoscalers | list, watch | Autoscaler state metrics. |
policy/poddisruptionbudgets | list, watch | Disruption-budget state metrics. |
node-exporter uses no Kubernetes API permissions.
You’re in control
- Disable the topology analyzer to remove cluster-wide Secret and pod-log read access:
--set topologyAnalyzer.enabled=false. This also turns off K8sGPT analysis and root-cause pod-log and Helm-release lookups. Add--set watcher.enabled=false --set liveRead.enabled=false --set da-monitoring.enabled=falseto remove cluster-wide ConfigMap read too. - Scope log reading to specific namespaces with
logWatcher.config.namespaces, or turn it off with--set logWatcher.enabled=false. This narrows what the log watcher reads; the permission to read pod logs cluster-wide stays while the topology analyzer is enabled. - Apply a ResourceQuota capping
count/secretson thedataagentnamespace for a hard ceiling on what the agent can create. - Audit at any time with the
helm template … | grep ClusterRolecommand above. - Manage RBAC yourself by installing with
--set rbac.create=falseand binding your own ServiceAccount.