Documentation menu

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, or patch verbs 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) and ghcr.io:443 (image pulls). The bundled monitoring pods’ images are pulled from quay.io, registry.k8s.io, and docker.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-creds mounted by api-server is missing key password”). 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=false

K8sGPT 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

ResourceVerbsWhy
secretscreate (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.
secretsget, update, delete on dataagent-mtls-credentials onlyRead 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/tokencreate on dataagent-live-read onlyRequest 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.

ResourceVerbsWhy
core/serviceslistScan well-known namespaces for a Prometheus Service when the Operator CRD isn’t present.
apiextensions.k8s.io/customresourcedefinitionsget (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/prometheuseslistWhen 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.

ResourceVerbsWhy
core/pods, nodes, eventsget, listResource inventory and event correlation for SRE golden signals (latency, errors, traffic, saturation).
apps/deployments, statefulsets, daemonsetsget, listWorkload-level signal attribution — link metrics back to the controller that owns the pod.
metrics.k8s.io/pods, nodesget, listRead 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.

ResourceVerbsWhy
core/pods, pods/log, pods/status, events, services, configmaps, secrets, persistentvolumeclaims, persistentvolumes, nodes, namespaces, serviceaccounts, resourcequotas, endpoints, limitrangesget, list, watchConfiguration objects K8sGPT reads to diagnose issues, plus pod-log and Helm-release (Secret) lookups during root-cause analysis.
apps/deployments, replicasets, statefulsets, daemonsetsget, list, watchWorkload graph and status.
batch/jobs, cronjobsget, list, watchBatch workload visibility.
networking.k8s.io/ingresses, ingressclasses, networkpoliciesget, list, watchNetwork topology and policy context.
discovery.k8s.io/endpointslicesget, list, watchMap Services to the pods behind them.
storage.k8s.io/storageclassesget, list, watchStorage topology and PVC binding diagnosis.
rbac.authorization.k8s.io/clusterroles, roles, clusterrolebindings, rolebindingsget, list, watchShow which service accounts are bound to which roles in the topology.
policy/poddisruptionbudgetsget, list, watchPDB-related disruption diagnosis.
autoscaling/horizontalpodautoscalersget, list, watchScaling-decision context.
apiextensions.k8s.io/customresourcedefinitionsget, list, watchCRD discovery for topology mapping.
cert-manager.io/certificatesget, list, watchCertificate status and expiry, when cert-manager is installed.
admissionregistration.k8s.io/mutatingwebhookconfigurations, validatingwebhookconfigurationsget, list, watchK8sGPT analyzer reads webhook configuration to diagnose admission-related failures.

Cluster-scoped — watcher (optional)

Created when watcher.enabled=true (the default).

ResourceVerbsWhy
core/events, configmapsget, list, watchReport 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.

ResourceVerbsWhy
core/podsget, list, watchFind the containers whose logs to read.
core/pods/loggetRead 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:

ResourceVerbsWhy
core/nodes, persistentvolumesget, listLook 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:

ResourceVerbsWhy
core/nodes, nodes/metrics, services, endpoints, pods, ingresses, configmapsget, list, watchDiscover scrape targets.
networking.k8s.io/ingresses, ingresses/statusget, list, watchDiscover scrape targets.
discovery.k8s.io/endpointslicesget, list, watchDiscover scrape targets.
non-resource URL /metricsgetRead the API server’s own metrics.

kube-state-metrics — turns object state into metrics:

ResourceVerbsWhy
core/pods, endpoints, persistentvolumeclaimslist, watchPod, endpoint, and volume-claim state metrics.
autoscaling/horizontalpodautoscalerslist, watchAutoscaler state metrics.
policy/poddisruptionbudgetslist, watchDisruption-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=false to 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/secrets on the dataagent namespace for a hard ceiling on what the agent can create.
  • Audit at any time with the helm template … | grep ClusterRole command above.
  • Manage RBAC yourself by installing with --set rbac.create=false and binding your own ServiceAccount.