The Hitchhiker's Guide to Observability - Limit Read Access to Traces - Part 8
- - 3 min read
In the previous articles, we deployed a distributed tracing infrastructure with TempoStack and OpenTelemetry Collector. We also deployed a Grafana instance to visualize the traces. The configuration was done in a way that allows everybody to read the traces. Every system:authenticated user is able to read ALL traces. This is usually not what you want. You want to limit trace access to only the appropriate namespace.
In this article, we’ll limit the read access to traces. The users of the team-a namespace will only be able to see their own traces.
Prerequisites
Verify Trace Access
Let’s verify what a user can see when they are authenticated. We have user1 who is a member of the team-a namespace. Let’s log in as this user and verify what they can see.
Navigate to Observability > Traces and select the tempostack/simplest datasource:

You should see the traces for the team-a namespace. This is fine—that’s what we want.
But now let’s change the tenant to tenantB and verify what the user can see.

As you can see, the user can see traces from the tenantB namespace, although they are a member of the team-a namespace. This is not what we want. We want to limit trace access to only the appropriate namespace.
The Original RBAC Configuration
In Part 2, we created a ClusterRoleBinding to grant read access to traces for everybody who is authenticated.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tempostack-traces-reader
subjects:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: 'system:authenticated'
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tempostack-traces-readerThis ClusterRoleBinding allows system:authenticated users to read all traces from all tenants and is bound to the ClusterRole tempostack-traces-reader.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tempostack-traces-reader
rules:
- verbs:
- get
apiGroups:
- tempo.grafana.com
resources:
- tenantA
- tenantB
resourceNames:
- tracesThis is the configuration we want to change. We want to limit read access to traces to only the appropriate namespace.
Change the RBAC Configuration
We will change the RBAC configuration to limit read access to traces. To do so, we will first create a new ClusterRole for the team-a namespace and bind it to users of that namespace.
Create the new ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tempostack-traces-reader-team-a (1)
rules:
- verbs:
- get
apiGroups:
- tempo.grafana.com
resources:
- tenantA (2)
resourceNames:
- traces| 1 | Name of the ClusterRole, now with the prefix team-a. |
| 2 | The Tenant that is allowed to read the traces. This time it is only the tenantA tenant. |
Create the new ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tempostack-traces-reader-team-a (1)
subjects:
- kind: User (2)
apiGroup: rbac.authorization.k8s.io
name: user1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tempostack-traces-reader-team-a (3)| 1 | Name of the ClusterRoleBinding, now with the prefix team-a. |
| 2 | The User that is allowed to read the traces. In this example: user1. |
| 3 | The ClusterRole that is allowed to read the traces. |
| In this example, we are using a single user. In a real-world scenario, you would most likely have a group of users. In that case, you would use a Group instead of a User. |
Modify the Original ClusterRole:
As a final step, we need to modify the original ClusterRole to remove tenantB from the list of tenants that are allowed to read the traces.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tempostack-traces-reader
rules:
- verbs:
- get
apiGroups:
- tempo.grafana.com
resources:
- tenantB (1)
resourceNames:
- traces| 1 | Only tenantA remains. Remove tenantB from the list of resources. |
This removes the permission to read traces from the tenantB namespace for the system:authenticated group.
| Eventually, the original ClusterRoleBinding might be deleted once every user has been assigned to a separate ClusterRole. |
Verify the Changes
Let’s see what these changes do. As user1, you should still be able to see the traces from the tenantA namespace.

But if you change the tenant to tenantB, you should see an error message like this:

| The user will still see the list of tenants. Hopefully, this will be fixed in a future version of TempoStack. |
Copyright © 2020 - 2025 Toni Schmidbauer & Thomas Jungbauer
Thomas Jungbauer
