Access and permissions for Grafana Alloy on Kubernetes
Alloy requires read access to Kubernetes API resources, node and container telemetry, and credentials for observability backends.
The Alloy container image runs as root by default and defines a non-root alloy user with UID 473 and GID 473.
Set securityContext, RBAC, and network settings to match the components in your configuration.
The Alloy Docker container image defines two users:
- A
rootuser. - A non-root user named
alloywith UID473and GID473.
Note
Components like beyla.ebpf and pyroscope.ebpf need root or additional Linux capabilities. Don’t set
capabilities.drop: [ALL]when these components are in your configuration. Refer to the component references for required capabilities and Pod settings.
Run as a non-root user
To run Alloy as a non-root user, configure a security context for the Alloy container.
If you use the Grafana Helm chart, add this to values.yaml:
alloy:
securityContext:
runAsUser: 473
runAsGroup: 473
global:
podSecurityContext:
fsGroup: 473
configReloader:
securityContext:
# this is the UID of the "nobody" user that the configReloader image runs as
runAsUser: 65534
runAsGroup: 65534This configuration runs the Alloy binary with UID 473 and GID 473 instead of as root.
It also runs the config reloader sidecar as UID 65534 and GID 65534.
Set container permissions
Set securityContext at the Pod and container level to limit filesystem writes, privilege escalation, and Linux capabilities:
spec:
securityContext:
runAsUser: 473
runAsGroup: 473
fsGroup: 473
runAsNonRoot: true
containers:
- name: alloy
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALLrunAsNonRoot: truecauses Kubernetes to reject the Pod if the image tries to run as root.readOnlyRootFilesystem: trueblocks writes to the container filesystem except on mounted volumes.allowPrivilegeEscalation: falseblocks privilege escalation beyond the parent process, regardless of file capabilities orsetuidbits.capabilities.drop: [ALL]removes all Linux capabilities from the container.
When you set readOnlyRootFilesystem: true, mount a writable volume at that path or change alloy.storagePath to a mounted volume.
Note
If you use components that need elevated host access, for example
beyla.ebpforpyroscope.ebpf, add the capabilities those components need. Don’t drop all capabilities when these components are in your configuration. Refer to the component references for required capabilities and volume mounts.
Restrict the HTTP server
The Grafana Helm chart sets alloy.listenAddr to 0.0.0.0 by default so other Pods can reach the container on port 12345.
Set alloy.listenAddr to 127.0.0.1 in values.yaml or restrict access with a NetworkPolicy when you don’t need cross-Pod access to the UI or /metrics endpoint.
The container image uses the binary default of 127.0.0.1:12345 when you don’t pass --server.http.listen-addr.
Refer to the http block for TLS and authentication options.
Kubernetes RBAC
Alloy needs RBAC permissions to interact with Kubernetes APIs.
The Helm chart creates a ClusterRole and ClusterRoleBinding when rbac.create is true.
The Helm chart sets rbac.rules and rbac.clusterRules in values.yaml.
Refer to the Grafana Helm chart values.yaml or README for the default rule blocks and the components each one supports.
To limit permissions, set rbac.rules and rbac.clusterRules to only the rule blocks your configuration uses.
Helm replaces each array in full, so copy the defaults and remove the blocks you don’t need.
Set rbac.create to false if you manage RBAC outside the chart.
Review the RBAC resources the Helm chart creates:
helm template alloy grafana/alloy --show-only templates/rbac.yaml

