Skip to content
Kong Logo | Kong Docs Logo
  • Docs
    • Explore the API Specs
      View all API Specs View all API Specs View all API Specs arrow image
    • Documentation
      API Specs
      Kong Gateway
      Lightweight, fast, and flexible cloud-native API gateway
      Kong Konnect
      Single platform for SaaS end-to-end connectivity
      Kong AI Gateway
      Multi-LLM AI Gateway for GenAI infrastructure
      Kong Mesh
      Enterprise service mesh based on Kuma and Envoy
      decK
      Helps manage Kong’s configuration in a declarative fashion
      Kong Ingress Controller
      Works inside a Kubernetes cluster and configures Kong to proxy traffic
      Kong Gateway Operator
      Manage your Kong deployments on Kubernetes using YAML Manifests
      Insomnia
      Collaborative API development platform
  • Plugin Hub
    • Explore the Plugin Hub
      View all plugins View all plugins View all plugins arrow image
    • Functionality View all View all arrow image
      View all plugins
      AI's icon
      AI
      Govern, secure, and control AI traffic with multi-LLM AI Gateway plugins
      Authentication's icon
      Authentication
      Protect your services with an authentication layer
      Security's icon
      Security
      Protect your services with additional security layer
      Traffic Control's icon
      Traffic Control
      Manage, throttle and restrict inbound and outbound API traffic
      Serverless's icon
      Serverless
      Invoke serverless functions in combination with other plugins
      Analytics & Monitoring's icon
      Analytics & Monitoring
      Visualize, inspect and monitor APIs and microservices traffic
      Transformations's icon
      Transformations
      Transform request and responses on the fly on Kong
      Logging's icon
      Logging
      Log request and response data using the best transport for your infrastructure
  • Support
  • Community
  • Kong Academy
Get a Demo Start Free Trial
Kong Mesh
2.2.x
  • Home icon
  • Kong Mesh
  • Features
  • Role-Based Access Control
github-edit-pageEdit this page
report-issueReport an issue
  • Kong Gateway
  • Kong Konnect
  • Kong Mesh
  • Kong AI Gateway
  • Plugin Hub
  • decK
  • Kong Ingress Controller
  • Kong Gateway Operator
  • Insomnia
  • Kuma

  • Docs contribution guidelines
  • dev
  • 2.10.x (latest)
  • 2.9.x
  • 2.8.x
  • 2.7.x (LTS)
  • 2.6.x
  • 2.5.x
  • 2.4.x
  • 2.3.x
  • 2.2.x
  • Introduction
    • About service meshes
    • Overview of Kong Mesh
    • How Kong Mesh works
    • Architecture
    • Stages of software availability
    • Version support policy
    • Mesh requirements
    • Release notes
  • Getting Started
  • Kong Mesh in Production
    • Overview
    • Deployment topologies
      • Overview
      • Standalone deployment
      • Multi-zone deployment
    • Install kumactl
    • Use Kong Mesh
    • Control plane deployment
      • Kong Mesh license
      • Deploy a standalone control plane
      • Deploy a multi-zone global control plane
      • Zone Ingress
      • Zone Egress
      • Configure zone proxy authentication
      • Control plane configuration reference
      • Systemd
    • Create multiple service meshes in a cluster
    • Data plane configuration
      • Data plane proxy
      • Configure the data plane on Kubernetes
      • Configure the data plane on Universal
      • Configure the Kong Mesh CNI
      • Configure transparent proxying
      • IPv6 support
    • Secure your deployment
      • Manage secrets
      • Authentication with the API server
      • Authentication with the data plane proxy
      • Configure data plane proxy membership
      • Secure access across services
      • Kong Mesh RBAC
      • FIPS support
    • Kong Mesh user interface
    • Upgrades and tuning
      • Upgrade Kong Mesh
      • Performance fine-tuning
  • Deploy
    • Explore Kong Mesh with the Kubernetes demo app
    • Explore Kong Mesh with the Universal demo app
  • Explore
    • Gateway
      • Delegated
      • Builtin
    • CLI
      • kumactl
    • Observability
      • Demo setup
      • Control plane metrics
      • Configuring Prometheus
      • Configuring Grafana
      • Configuring Datadog
      • Observability in multi-zone
    • Inspect API
      • Matched policies
      • Affected data plane proxies
      • Envoy proxy configuration
    • Kubernetes Gateway API
      • Installation
      • Usage
      • TLS termination
      • Customization
      • Multi-mesh
      • Multi-zone
      • How it works
  • Networking
    • Service Discovery
    • DNS
      • How it works
      • Installation
      • Configuration
      • Usage
    • Non-mesh traffic
      • Incoming
      • Outgoing
    • Transparent Proxying
  • Monitor & manage
    • Dataplane Health
      • Circuit Breaker Policy
      • Kubernetes and Universal Service Probes
      • Health Check Policy
    • Control Plane Configuration
      • Modifying the configuration
      • Inspecting the configuration
      • Store
  • Policies
    • Introduction
    • General notes about Kong Mesh policies
    • Applying Policies
    • How Kong Mesh chooses the right policy to apply
    • Understanding TargetRef policies
    • Protocol support in Kong Mesh
    • Mutual TLS
      • Usage of "builtin" CA
      • Usage of "provided" CA
      • Permissive mTLS
      • Certificate Rotation
    • Traffic Permissions
      • Usage
      • Access to External Services
    • Traffic Route
      • Usage
    • Traffic Metrics
      • Expose metrics from data plane proxies
      • Expose metrics from applications
      • Override Prometheus settings per data plane proxy
      • Filter Envoy metrics
      • Secure data plane proxy metrics
    • Traffic Trace
      • Add a tracing backend to the mesh
      • Add TrafficTrace resource
    • Traffic Log
      • Add a logging backend
      • Add a TrafficLog resource
      • Logging external services
      • Builtin Gateway support
      • Access Log Format
    • Locality-aware Load Balancing
      • Enabling locality-aware load balancing
    • Fault Injection
      • Usage
      • Matching
    • Health Check
      • Usage
      • Matching
    • Circuit Breaker
      • Usage
      • Matching
      • Builtin Gateway support
      • Non-mesh traffic
    • External Service
      • Usage
      • Builtin Gateway support
    • Retry
      • Usage
      • Matching
      • Builtin Gateway support
    • Timeout
      • Usage
      • Configuration
      • Default general-purpose Timeout policy
      • Matching
      • Builtin Gateway support
      • Inbound timeouts
      • Non-mesh traffic
    • Rate Limit
      • Usage
      • Matching destinations
      • Builtin Gateway support
    • Virtual Outbound
      • Examples
    • MeshGateway
      • TLS Termination
    • MeshGatewayRoute
      • Listener tags
      • Matching
      • Filters
      • Reference
    • MeshGatewayInstance
    • Service Health Probes
      • Kubernetes
      • Universal probes
    • MeshAccessLog (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshCircuitBreaker (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshFaultInjection (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshHealthCheck (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshHTTPRoute (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
      • Merging
    • MeshProxyPatch (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
      • Merging
    • MeshRateLimit (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshRetry (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshTimeout (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshTrace (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshTrafficPermission (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • MeshLoadBalancingStrategy (Beta)
      • TargetRef support matrix
      • Configuration
      • Examples
    • OPA policy
    • MeshOPA (beta)
    • MeshGlobalRateLimit (beta)
  • Enterprise Features
    • Overview
    • HashiCorp Vault CA
    • Amazon ACM Private CA
    • cert-manager Private CA
    • OPA policy support
    • MeshOPA (beta)
    • Multi-zone authentication
    • FIPS support
    • Certificate Authority rotation
    • Role-Based Access Control
    • UBI Images
    • Windows Support
    • ECS Support
    • Auditing
    • MeshGlobalRateLimit (beta)
  • Reference
    • HTTP API
    • Kubernetes annotations and labels
    • Kuma data collection
    • Control plane configuration reference
    • Envoy proxy template
  • Community
    • Contribute to Kuma
enterprise-switcher-icon Switch to OSS
On this pageOn this page
  • How it works
    • AccessRole
    • AccessRoleBinding
  • Example roles
    • Kong Mesh operator (admin)
    • Service owner
    • Observability operator
    • Single Mesh operator
  • Kubernetes
  • Default
  • Example
  • Multi-zone
  • Wildcard tag value matching
  • What should I do if I’ve locked myself out?
You are browsing documentation for an older version. See the latest documentation here.

Role-Based Access Control
Available with Kong Gateway Enterprise subscription - Contact Sales

Role-Based Access Control (RBAC) lets you restrict access to resources and actions to specified users or groups, based on user roles.

How it works

Kong Mesh provides two resources to implement RBAC:

  • AccessRole specifies kinds of access and resources to which access is granted. Note that access is defined only for write operations. Read access is available to all users.
  • AccessRoleBinding lists users and the access roles that are assigned to them.

AccessRole

AccessRole defines a role that is assigned separately to users. It is global-scoped, which means it is not bound to a mesh.

"targetRef" selectors
Source and Destination selectors

For policies using the targetRef selector. You can specify which targetRef kinds users should have access to.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: role-1
spec:
  rules:
  - types: ["MeshTrafficPermission", "MeshTrace", "MeshAccessLog"] # List of Kuma resource kinds that are granted access. If it's empty, access is granted to all kinds.
    names: ["res-1"] # List of allowed type names that are granted access. If it's empty, access is granted to resources regardless of the name.
    mesh: default # Grants access to the resources in the named mesh. It can only be used with the mesh-scoped resources.
    access: ["CREATE", "UPDATE", "DELETE"] # The action bound to a type.
    when: # A set of qualifiers to receive access. Only one of them needs to be fulfilled to receive access.
    - targetRef: # A condition on the targetRef section in policies 2.0 (like MeshAccessLog or MeshTrace).
        kind: MeshService
        name: backend
    - targetRef:
        kind: MeshSubset
        tags:
          k8s.kuma.io/namespace: kuma-demo
    - targetRef:
        kind: MeshService
        name: web
      to: # can only be used with policies that have a "to" list (like MeshAccessLog)
        targetRef:
          kind: MeshService
          name: backend
    - targetRef:
        kind: MeshService
        name: web
      from: # can only be used with policies that have a "from" list (like MeshTrafficPermission)
        targetRef:
          kind: Mesh
type: AccessRole
name: role-1
rules:
- types: ["MeshTrafficPermission", "MeshTrace", "MeshAccessLog"] # List of Kuma resource types that are granted access. If it's empty, access is granted to all types.
  names: ["res-1"] # List of allowed type names that are granted access. If it's empty, access is granted to resources regardless of the name.
  mesh: default # Grants access to the resources in the named mesh. It can only be used with the mesh-scoped resources.
  access: ["CREATE", "UPDATE", "DELETE"] # The action bound to a type.
  when: # A set of qualifiers to receive access. Only one of them needs to be fulfilled to receive access.
  - targetRef: # A condition on the targetRef section in policies 2.0 (like MeshAccessLog or MeshTrace).
      kind: MeshService
      name: backend
  - targetRef:
      kind: MeshSubset
      tags:
        k8s.kuma.io/namespace: kuma-demo
  - targetRef:
      kind: MeshService
      name: web
    to: # can only be used with policies that have a "to" list (like MeshAccessLog)
      targetRef:
        kind: MeshService
        name: backend
  - targetRef:
      kind: MeshService
      name: web
    from: # can only be used with policies that have a "from" list (like MeshTrafficPermission)
      targetRef:
        kind: Mesh

The lack of targetRef, from, or to means that a user can specify anything in this section. For example, the when element with a specific from section allows the user to pick anything for targetRef in the policy.

If the policy contains multiple to elements, you must specify an RBAC qualifier for every single to element.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: role-1
spec:
  rules:
  - types: ["TrafficPermission", "TrafficRoute", "Mesh"] # list of Kuma resource kinds to which access is granted. If empty, then access is granted to all kinds
    names: ["res-1"] # list of allowed names of types to which access is granted. If empty, then access is granted to resources regardless of the name.
    mesh: default # Mesh within which the access to resources is granted. It can only be used with the Mesh-scoped resources.
    access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"] # an action that is bound to a type.
    when: # a set of qualifiers to receive access. Only one of them needs to be fulfilled to receive an access
    - sources: # a condition on sources section in connection policies (like TrafficRoute or HealthCheck). If missing, then all sources are allowed
        match:
          kuma.io/service: web
      destinations: # a condition on destinations section in connection policies (like TrafficRoute or HealthCheck). If missing, then all destinations are allowed
        match:
          kuma.io/service: backend
    - selectors: # a condition on selectors section in dataplane policies (like TrafficTrace or ProxyTemplate).
        match:
          kuma.io/service: web
    - dpToken: # a condition on generate dataplane token.
        tags:
        - name: kuma.io/service
          value: web
type: AccessRole
name: role-1
rules:
- types: ["TrafficPermission", "TrafficRoute", "Mesh"] # list of Kuma resource types to which access is granted. If empty, then access is granted to all types
  names: ["res-1"] # list of allowed names of types to which access is granted. If empty, then access is granted to resources regardless of the name.
  mesh: default # Mesh within which the access to resources is granted. It can only be used with the Mesh-scoped resources.
  access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"] # an action that is bound to a type.
  when: # a set of qualifiers to receive access. Only one of them needs to be fulfilled to receive an access
  - sources: # a condition on sources section in connection policies (like TrafficRoute or HealthCheck). If missing, then all sources are allowed
      match:
        kuma.io/service: web
    destinations: # a condition on destinations section in connection policies (like TrafficRoute or HealthCheck). If missing, then all destinations are allowed
      match:
        kuma.io/service: backend
  - selectors: # a condition on selectors section in dataplane policies (like TrafficTrace or ProxyTemplate).
      match:
        kuma.io/service: web
  - dpToken: # a condition on generate dataplane token.
      tags:
      - name: kuma.io/service
        value: web

Important: Granting access actions without binding them to specific resource types provides full access, including to Secrets and GlobalSecrets, posing security risks. For example, an AccessRole with access: ["CREATE", "UPDATE", "DELETE"] and no defined types allows modifying any resource, including secrets. Even without GENERATE_DATAPLANE_TOKEN, GENERATE_USER_TOKEN, GENERATE_ZONE_CP_TOKEN, or GENERATE_ZONE_TOKEN, the user can retrieve secrets and use them to generate tokens manually. To prevent this, always bind access actions to specific resource types. Instead of unrestricted access, explicitly define allowed types, such as types: ["MeshHTTPRoute", "MeshTCPRoute", "MeshTrace"], to ensure the role can only manage those resources and not secrets or other sensitive data.

AccessRoleBinding

AccessRoleBinding assigns a set of AccessRoles to a list of subjects (users or groups). Because these bindings are global in scope, they apply across all meshes, allowing centralized management of permissions.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRoleBinding
metadata:
  name: binding-1
spec:
  subjects:
  - type: User
    name: john.doe@example.com
  - type: Group
    name: team-a
  roles:
  - role-1
type: AccessRoleBinding
name: binding-1
subjects:
- type: User
  name: john.doe@example.com
- type: Group
  name: team-a
roles:
- role-1

Restricting the default AccessRoleBinding

Important: By default, Kong Mesh assigns the admin role to everyone in the mesh-system:authenticated and mesh-system:unauthenticated groups. This means every user automatically gets admin rights, even if you create a custom binding for them, they will also inherit the default admin role.

To limit admin privileges to a specific group, update the default binding. For example, to grant admin rights only to members of the mesh-system:admin group, replace the default binding with the following:

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRoleBinding
metadata:
  name: default
spec:
  subjects:
  - type: Group
    name: mesh-system:admin
  # The `system:serviceaccounts:kube-system` group is required by Kubernetes controllers to manage Kong Mesh 
  # resources, for example, cleaning up data plane objects when a namespace is removed.
  - type: Group
    name: system:serviceaccounts:kube-system
  roles:
  - admin
type: AccessRoleBinding
name: default
subjects:
- type: Group
  name: mesh-system:admin
roles:
- admin

Example roles

Let’s go through example roles in the organization that can be created using Kong Mesh RBAC.

Kong Mesh operator (admin)

Mesh operator is a part of infrastructure team responsible for Kong Mesh deployment.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: admin
spec:
  rules:
  - access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"]
type: AccessRole
name: admin
rules:
- access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"]

This way Kong Mesh operators can execute any action.

Note: This role is automatically created on the start of the control plane.

Service owner

Service owner is a part of team responsible for given service. Let’s take a backend service as an example.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: backend-owner
spec:
  rules:
  - mesh: default
    types: ["MeshTrafficPermission", "MeshRateLimit"]
    access: ["CREATE", "DELETE", "UPDATE"]
    when:
    - targetRef:
        kind: MeshService
        name: backend
  - mesh: default
    types: ["MeshHTTPRoute", "MeshHealthCheck", "MeshCircuitBreaker", "MeshFaultInjection", "MeshRetry", "MeshTimeout", "MeshAccessLog"]
    access: ["CREATE", "DELETE", "UPDATE"]
    when:
    - targetRef:
        kind: Mesh
      from:
        targetRef:
          kind: MeshSubset
          tags:
            kuma.io/service: backend
    - targetRef:
        kind: Mesh
      to:
        targetRef:
          kind: MeshService
          name: backend
  - mesh: default
    types: ["MeshTrace", "MeshProxyPatch"]
    access: ["CREATE", "DELETE", "UPDATE"]
    when:
    - targetRef:
        kind: MeshService
        name: backend
type: AccessRole
name: backend-owner
rules:
- mesh: default
  types: ["MeshTrafficPermission", "MeshRateLimit"]
  access: ["CREATE", "DELETE", "UPDATE"]
  when:
  - targetRef:
      kind: MeshService
      name: backend
- mesh: default
  types: ["MeshHTTPRoute", "MeshHealthCheck", "MeshCircuitBreaker", "MeshFaultInjection", "MeshRetry", "MeshTimeout", "MeshAccessLog"]
  access: ["CREATE", "DELETE", "UPDATE"]
  when:
  - targetRef:
      kind: Mesh
    from:
      targetRef:
        kind: MeshSubset
        tags:
          kuma.io/service: backend
  - targetRef:
      kind: Mesh
    to:
      targetRef:
        kind: MeshService
        name: backend
- mesh: default
  types: ["MeshTrace", "MeshProxyPatch"]
  access: ["CREATE", "DELETE", "UPDATE"]
  when:
  - targetRef:
      kind: MeshService
      name: backend
  • Modify MeshRateLimit and MeshTrafficPermission that allows/restricts access to the backend service. This changes the configuration of the data plane proxy that implements the backend service.
  • Modify connection policies (MeshHTTPRoute, MeshHealthCheck, MeshCircuitBreaker, MeshFaultInjection, MeshRetry, MeshTimeout, MeshRateLimit, MeshAccessLog) that matches the backend service that connects to other services. This changes the configuration of the data plane proxy that implements the backend service.
  • Modify connection policies that matches any service that consumes backend service. This changes the configuration of data plane proxies that are connecting to the backend, but the configuration only affects connections to the backend service. It’s useful because the service owner of the backend knows what (MeshTimeout, MeshHealthCheck) should be applied when communicating with their service.
  • Modify the MeshTrace or MeshProxyPatch that matches the backend service. This changes the configuration of the data plane proxy that implements the backend service.

Note: When giving users UPDATE permission, remember to add UPDATE permission to all selectors they can switch between. For example, if a user only has access to sources selector, they won’t be able to update policy with destinations selector or new targetRef selectors. Likewise, when a user only has access to the targetRef kind MeshService, they won’t be able to update the policy to use a different targetRef kind.

Observability operator

We may also have an infrastructure team which is responsible for the logging/metrics/tracing systems in the organization. Currently, those features are configured on Mesh, MeshAccessLog, and MeshTrace objects.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: observability-operator
spec:
  rules:
  - mesh: '*'
    types: ["MeshAccessLog", "MeshTrace"]
    access: ["CREATE", "DELETE", "UPDATE"]
  - types: ["Mesh"]
    access: ["CREATE", "DELETE", "UPDATE"]
type: AccessRole
name: observability-operator
rules:
- mesh: '*'
  types: ["MeshAccessLog", "MeshTrace"]
  access: ["CREATE", "DELETE", "UPDATE"]
- types: ["Mesh"]
  access: ["CREATE", "DELETE", "UPDATE"]

This way an observability operator can:

  • Modify MeshAccessLog and MeshTrace in any mesh
  • Modify any Mesh

Single Mesh operator

Kong Mesh lets us segment the deployment into many logical service meshes configured by Mesh object. We may want to give access to one specific Mesh and all objects connected with this Mesh.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: demo-mesh-operator
spec:
  rules:
  - mesh: demo
    access: ["CREATE", "DELETE", "UPDATE"]
  - types: ["Mesh"]
    names: ["demo"]
    access: ["CREATE", "DELETE", "UPDATE"]
type: AccessRole
name: demo-mesh-operator
rules:
- mesh: demo
  access: ["CREATE", "DELETE", "UPDATE"]
- types: ["Mesh"]
  names: ["demo"]
  access: ["CREATE", "DELETE", "UPDATE"]

This way all observability operator can:

  • Modify all resources in the demo mesh
  • Modify demo Mesh object.

Kubernetes

Kubernetes provides their own RBAC system, but it’s not sufficient to cover use cases for several reasons:

  • You cannot restrict access to resources of specific Mesh
  • You cannot restrict access based on the content of the policy

Kong Mesh RBAC works on top of Kubernetes RBAC. For example, to restrict the access for a user to modify MeshTrafficPermission for backend service, they need to be able to create MeshTrafficPermission in the first place.

The subjects in AccessRoleBinding are compatible with Kubernetes users and groups. Kong Mesh RBAC on Kubernetes is implemented using Kubernetes Webhook when applying resources. This means you can only use Kubernetes users and groups for CREATE, DELETE and UPDATE access. GENERATE_DATAPLANE_TOKEN, GENERATE_USER_TOKEN, GENERATE_ZONE_CP_TOKEN, GENERATE_ZONE_TOKEN are used when interacting with Kong Mesh API Server, in this case you need to use the user token.

Default

Kong Mesh creates an admin AccessRole that allows every action.

In a standalone deployment, the default AccessRoleBinding assigns this role to every authenticated and unauthenticated user.

In a multi-zone deployment, the default AccessRoleBinding on the global control plane assigns this role to every authenticated and unauthenticated user. However, on the zone control plane, the default AccessRoleBinding is restricted to the admin AccessRole only.

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: admin
spec:
  rules:
  - access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"]
---
apiVersion: kuma.io/v1alpha1
kind: AccessRoleBinding
metadata:
  name: default
spec:
  subjects:
  - type: Group
    name: mesh-system:authenticated
  - type: Group
    name: mesh-system:unauthenticated
  - type: Group
    name: system:authenticated
  - type: Group
    name: system:unauthenticated
  roles:
  - admin
type: AccessRole
name: admin
rules:
- access: ["CREATE", "UPDATE", "DELETE", "GENERATE_DATAPLANE_TOKEN", "GENERATE_USER_TOKEN", "GENERATE_ZONE_CP_TOKEN", "GENERATE_ZONE_TOKEN"]
---
type: AccessRoleBinding
name: default
subjects:
- type: Group
  name: mesh-system:authenticated
- type: Group
  name: mesh-system:unauthenticated
roles:
- admin

To restrict access to admin only, change the default AccessRole policy:

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRoleBinding
metadata:
  name: default
spec:
  subjects:
  - type: Group
    name: mesh-system:admin
  - type: Group
    name: system:masters
  # The `system:serviceaccounts:kube-system` group is required by Kubernetes controllers to manage Kong Mesh 
  # resources, for example, cleaning up data plane objects when a namespace is removed.
  - type: Group
    name: system:serviceaccounts:kube-system
  roles:
  - admin
type: AccessRoleBinding
name: default
subjects:
- type: Group
  name: mesh-system:admin
roles:
- admin

Example

"targetRef" selectors
Source and Destination selectors

The following steps create a new user and restrict the access to only MeshTrafficPermission for the backend service.

Kubernetes
Universal
  1. Create a backend-owner Kubernetes user and configure kubectl:

     mkdir -p /tmp/k8s-certs
     cd /tmp/k8s-certs
     openssl genrsa -out backend-owner.key 2048 # generate client key
     openssl req -new -key backend-owner.key -subj "/CN=backend-owner" -out backend-owner.csr # generate client certificate request
     CSR=$(cat backend-owner.csr | base64 | tr -d "\n") && echo "apiVersion: certificates.k8s.io/v1
     kind: CertificateSigningRequest
     metadata:
       name: backend-owner
     spec:
       request: $CSR
       signerName: kubernetes.io/kube-apiserver-client
       usages:
       - client auth" | kubectl apply -f -
     kubectl certificate approve backend-owner
     kubectl get csr backend-owner -o jsonpath='{.status.certificate}'| base64 -d > backend-owner.crt
     kubectl config set-credentials backend-owner \
     --client-key=/tmp/k8s-certs/backend-owner.key \
     --client-certificate=/tmp/k8s-certs/backend-owner.crt \
     --embed-certs=true
     kubectl config set-context backend-owner --cluster=YOUR_CLUSTER_NAME --user=backend-owner
    
  2. Create Kubernetes RBAC to allow backend-owner to manage all MeshTrafficPermission:

     echo "
     ---
     apiVersion: rbac.authorization.k8s.io/v1
     kind: ClusterRole
     metadata:
       name: kuma-policy-management
     rules:
     - apiGroups:
       - kuma.io
       resources:
       - meshtrafficpermissions
       verbs:
       - get
       - list
       - watch
       - create
       - update
       - patch
       - delete
     ---
     apiVersion: rbac.authorization.k8s.io/v1
     kind: ClusterRoleBinding
     metadata:
       name: kuma-policy-management-backend-owner
     roleRef:
       apiGroup: rbac.authorization.k8s.io
       kind: ClusterRole
       name: kuma-policy-management
     subjects:
     - kind: User
       name: backend-owner
       apiGroup: rbac.authorization.k8s.io
     " | kubectl apply -f -
    
  3. Change default Kong Mesh RBAC to restrict access to resources by default:

     echo "
     apiVersion: kuma.io/v1alpha1
     kind: AccessRoleBinding
     metadata:
       name: default
     spec:
       subjects:
       - type: Group
         name: mesh-system:admin
       - type: Group
         name: system:masters
       - type: Group
         name: system:serviceaccounts:kube-system
       roles:
       - admin
     " | kubectl apply -f -
    
  4. Create an AccessRole to grant permissions to user backend-owner to modify MeshTrafficPermission only for the backend service:

     echo '
     ---
     apiVersion: kuma.io/v1alpha1
     kind: AccessRole
     metadata:
       name: backend-owner
     spec:
       rules:
       - types: ["MeshTrafficPermission"]
         mesh: default
         access: ["CREATE", "UPDATE", "DELETE"]
         when:
         - targetRef:
             kind: MeshService
             name: backend
     ---
     apiVersion: kuma.io/v1alpha1
     kind: AccessRoleBinding
     metadata:
       name: backend-owners
     spec:
       subjects:
       - type: User
         name: backend-owner
       roles:
       - backend-owner
     ' | kubectl apply -f -
    
  5. Change the service to test user access:

     kubectl config use-context backend-owner
     echo "
     apiVersion: kuma.io/v1alpha1
     kind: MeshTrafficPermission
     metadata:
       name: web-to-backend
       namespace: kong-mesh-system
       labels:
         kuma.io/mesh: default
     spec:
       targetRef:
         kind: MeshService
         name: backend
       from:
       - targetRef:
           kind: MeshService
           name: web
         default:
           action: ALLOW
     " | kubectl apply -f -
     # operation should succeed, access to backend service access is granted
    
     echo "
     apiVersion: kuma.io/v1alpha1
     kind: MeshTrafficPermission
     metadata:
       name: web-to-backend
       namespace: kong-mesh-system
       labels:
         kuma.io/mesh: default
     spec:
       targetRef:
         kind: MeshService
         name: not-backend # access to this service is not granted
       from:
       - targetRef:
           kind: MeshService
           name: web
         default:
           action: ALLOW
     " | kubectl apply -f -
     # operation should not succeed
    

The following steps create a new user and restrict the access to only TrafficPermission for the backend service.

Note: By default, all requests that originate from localhost are authenticated as the admin user in the mesh-system:admin group. For this example to work, you must either run the control plane with KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN set to false or access the control plane using a method other than localhost.

  1. Extract the admin token and configure kumactl with the admin:

     export ADMIN_TOKEN=$(curl http://localhost:5681/global-secrets/admin-user-token | jq -r .data | base64 -d)
     kumactl config control-planes add \
     --name=cp-admin \
     --address=https://localhost:5682 \
     --skip-verify=true \
     --auth-type=tokens \
     --auth-conf token=$ADMIN_TOKEN
    
  2. Configure backend-owner:

     export BACKEND_OWNER_TOKEN=$(kumactl generate user-token --valid-for=24h --name backend-owner)
     kumactl config control-planes add \
     --name=cp-backend-owner \
     --address=https://localhost:5682 \
     --skip-verify=true \
     --auth-type=tokens \
     --auth-conf token=$BACKEND_OWNER_TOKEN
     kumactl config control-planes switch --name cp-admin # switch back to admin
    
  3. Change default Kong Mesh RBAC to restrict access to resources by default:

     echo "type: AccessRoleBinding
     name: default
     subjects:
     - type: Group
       name: mesh-system:admin
     roles:
     - admin" | kumactl apply -f -
    
  4. Create Kong Mesh RBAC to only allow the backend-owner to modify MeshTrafficPermission for backend:

     echo '
     type: AccessRole
     name: backend-owner
     rules:
     - types: ["MeshTrafficPermission"]
       mesh: default
       access: ["CREATE", "UPDATE", "DELETE"]
       when:
       - targetRef:
           kind: MeshService
           name: backend
     ' | kumactl apply -f -
     echo '
     type: AccessRoleBinding
     name: backend-owners
     subjects:
     - type: User
       name: backend-owner
     roles:
     - backend-owner' | kumactl apply -f -
    
  5. Change the user and test RBAC:

     kumactl config control-planes switch --name cp-backend-owner
     echo "
     type: MeshTrafficPermission
     mesh: default
     name: web-to-backend
     spec:
       targetRef:
         kind: MeshService
         name: backend
       from:
       - targetRef:
           kind: MeshService
           name: web
         default:
           action: ALLOW
     " | kumactl apply -f -
     # this operation should succeed
    
     echo "
     type: MeshTrafficPermission
     mesh: default
     name: web-to-backend
     spec:
       targetRef:
         kind: MeshService
         name: not-backend
       from:
       - targetRef:
           kind: MeshService
           name: web
         default:
           action: ALLOW
     " | kumactl apply -f -
     Error: Access Denied (user "backend-owner/mesh-system:authenticated" cannot access the resource)
    
Kubernetes
Universal
  1. Create a backend-owner Kubernetes user and configure kubectl:

     mkdir -p /tmp/k8s-certs
     cd /tmp/k8s-certs
     openssl genrsa -out backend-owner.key 2048 # generate client key
     openssl req -new -key backend-owner.key -subj "/CN=backend-owner" -out backend-owner.csr # generate client certificate request
     CSR=$(cat backend-owner.csr | base64 | tr -d "\n") && echo "apiVersion: certificates.k8s.io/v1
     kind: CertificateSigningRequest
     metadata:
       name: backend-owner
     spec:
       request: $CSR
       signerName: kubernetes.io/kube-apiserver-client
       usages:
       - client auth" | kubectl apply -f -
     kubectl certificate approve backend-owner
     kubectl get csr backend-owner -o jsonpath='{.status.certificate}'| base64 -d > backend-owner.crt
     kubectl config set-credentials backend-owner \
     --client-key=/tmp/k8s-certs/backend-owner.key \
     --client-certificate=/tmp/k8s-certs/backend-owner.crt \
     --embed-certs=true
     kubectl config set-context backend-owner --cluster=YOUR_CLUSTER_NAME --user=backend-owner
    
  2. Create Kubernetes RBAC to allow backend-owner to manage all TrafficPermission:

     echo "
     ---
     apiVersion: rbac.authorization.k8s.io/v1
     kind: ClusterRole
     metadata:
       name: kuma-policy-management
     rules:
     - apiGroups:
       - kuma.io
       resources:
       - trafficpermissions
       verbs:
       - get
       - list
       - watch
       - create
       - update
       - patch
       - delete
     ---
     apiVersion: rbac.authorization.k8s.io/v1
     kind: ClusterRoleBinding
     metadata:
       name: kuma-policy-management-backend-owner
     roleRef:
       apiGroup: rbac.authorization.k8s.io
       kind: ClusterRole
       name: kuma-policy-management
     subjects:
     - kind: User
       name: backend-owner
       apiGroup: rbac.authorization.k8s.io
     " | kubectl apply -f -
    
  3. Change default Kong Mesh RBAC to restrict access to resources by default:

     echo "
     apiVersion: kuma.io/v1alpha1
     kind: AccessRoleBinding
     metadata:
       name: default
     spec:
       subjects:
       - type: Group
         name: mesh-system:admin
       - type: Group
         name: system:masters
       - type: Group
         name: system:serviceaccounts:kube-system
       roles:
       - admin
     " | kubectl apply -f -
    
  4. Create an AccessRole to grant permissions to the backend-owner user to modify TrafficPermission only for the backend service:

     echo '
     ---
     apiVersion: kuma.io/v1alpha1
     kind: AccessRole
     metadata:
       name: backend-owner
     spec:
       rules:
       - types: ["TrafficPermission"]
         mesh: default
         access: ["CREATE", "UPDATE", "DELETE"]
         when:
         - destinations:
             match:
               kuma.io/service: backend
     ---
     apiVersion: kuma.io/v1alpha1
     kind: AccessRoleBinding
     metadata:
       name: backend-owners
     spec:
       subjects:
       - type: User
         name: backend-owner
       roles:
       - backend-owner
     ' | kubectl apply -f -
    
  5. Change the service to test user access:

     kubectl config use-context backend-owner
     echo "
     apiVersion: kuma.io/v1alpha1
     kind: TrafficPermission
     mesh: default
     metadata:
       name: web-to-backend
     spec:
       sources:
       - match:
           kuma.io/service: web
       destinations:
       - match:
           kuma.io/service: backend
     " | kubectl apply -f -
     # operation should succeed, access to backend service access is granted
    
     echo "
     apiVersion: kuma.io/v1alpha1
     kind: TrafficPermission
     mesh: default
     metadata:
       name: web-to-backend
     spec:
       sources:
       - match:
           kuma.io/service: web
       destinations:
       - match:
           kuma.io/service: not-backend # access to this service is not granted
     " | kubectl apply -f -
     # operation should not succeed
    

Note: By default, all requests that originates from localhost are authenticated as the admin user belonging to the mesh-system:admin group. For this example to work, you must either run the control plane with KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN set to false or access the control plane via a method other than localhost.

  1. Extract admin token and configure kumactl with admin:

     export ADMIN_TOKEN=$(curl http://localhost:5681/global-secrets/admin-user-token | jq -r .data | base64 -d)
     kumactl config control-planes add \
     --name=cp-admin \
     --address=https://localhost:5682 \
     --skip-verify=true \
     --auth-type=tokens \
     --auth-conf token=$ADMIN_TOKEN
    
  2. Configure backend-owner:

     export BACKEND_OWNER_TOKEN=$(kumactl generate user-token --valid-for=24h --name backend-owner)
     kumactl config control-planes add \
     --name=cp-backend-owner \
     --address=https://localhost:5682 \
     --skip-verify=true \
     --auth-type=tokens \
     --auth-conf token=$BACKEND_OWNER_TOKEN
     kumactl config control-planes switch --name cp-admin # switch back to admin
    
  3. Change default Kong Mesh RBAC to restrict access to resources by default:

     echo "type: AccessRoleBinding
     name: default
     subjects:
     - type: Group
       name: mesh-system:admin
     roles:
     - admin" | kumactl apply -f -
    
  4. Create Kong Mesh RBAC to restrict backend-owner to only modify TrafficPermission for backend:

     echo '
     type: AccessRole
     name: backend-owner
     rules:
     - types: ["TrafficPermission"]
       mesh: default
       access: ["CREATE", "UPDATE", "DELETE"]
       when:
       - destinations:
           match:
             kuma.io/service: backend
     ' | kumactl apply -f -
     echo '
     type: AccessRoleBinding
     name: backend-owners
     subjects:
     - type: User
       name: backend-owner
     roles:
     - backend-owner' | kumactl apply -f -
    
  5. Change the user and test RBAC:

     kumactl config control-planes switch --name cp-backend-owner
     echo "
     type: TrafficPermission
     mesh: default
     name: web-to-backend
     sources:
     - match:
         kuma.io/service: web
     destinations:
     - match:
         kuma.io/service: backend
     " | kumactl apply -f -
     # this operation should succeed
    
     echo "
     type: TrafficPermission
     mesh: default
     name: web-to-backend
     sources:
     - match:
         kuma.io/service: web
     destinations:
     - match:
         kuma.io/service: other
     " | kumactl apply -f -
     Error: Access Denied (user "backend-owner/mesh-system:authenticated" cannot access the resource)
    

Multi-zone

In a multi-zone setup, AccessRole and AccessRoleBinding are not synchronized between the global control plane and the zone control plane.

Wildcard tag value matching

Note: This feature is available starting in Kong Mesh 1.9.1

Note: This feature currently only works with “Source and Destination” selectors. This limitation restricts using newer policy types like MeshTrafficPermission, MeshAccessLog, or MeshHTTPRoute.

You can perform partial tag value matching using * wildcards.

For example, the following role:

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: AccessRole
metadata:
  name: role-wildcard
spec:
  rules:
  - types: ["TrafficRoute"]
    mesh: default
    access: ["CREATE", "UPDATE", "DELETE"]
    when:
    - sources:
        match:
          k8s.kuma.io/namespace: orders
      destinations:
        match:
          kuma.io/service: '*_orders_*'
type: AccessRole
name: role-wildcard
rules:
- types: ["TrafficRoute"]
  mesh: default
  access: ["CREATE", "UPDATE", "DELETE"]
  when:
  - sources:
      match:
        k8s.kuma.io/namespace: orders
    destinations:
      match:
        kuma.io/service: '*_orders_*'

would allow a subject to create the following resource:

Kubernetes
Universal
apiVersion: kuma.io/v1alpha1
kind: TrafficRoute
metadata:
  name: tr-orders
spec:
  sources:
  - match:
      k8s.kuma.io/namespace: 'orders'
  destinations:
  - match:
      kuma.io/service: web_orders_svc_1000
  - match:
      kuma.io/service: backend_orders_svc_1000
  conf:
    destination:
      kuma.io/service: '*'
type: TrafficRoute
mesh: default
name: tr-orders
sources:
- match:
    k8s.kuma.io/namespace: 'orders'
destinations:
- match:
    kuma.io/service: web_orders_svc_1000
- match:
    kuma.io/service: backend_orders_svc_1000
conf:
  destination:
    kuma.io/service: '*'

What should I do if I’ve locked myself out?

If you remove the default AccessRoleBinding and AccessRole, you might find yourself locked out and unable to edit any resources. If you encounter this situation, you can regain access to the cluster by following these steps:

  1. Configure the control-plane by setting the: KUMA_ACCESS_TYPE environment variable to static, and then restart the control-plane.
  2. Create the default AccessRoleBinding and AccessRole (as described in the default section), or add new groups if necessary.
  3. Remove the KUMA_ACCESS_TYPE environment variable for the control-plane and restart the control-plane.
Thank you for your feedback.
Was this page useful?
Too much on your plate? close cta icon
More features, less infrastructure with Kong Konnect. 1M requests per month for free.
Try it for Free
  • Kong
    Powering the API world

    Increase developer productivity, security, and performance at scale with the unified platform for API management, service mesh, and ingress controller.

    • Products
      • Kong Konnect
      • Kong Gateway Enterprise
      • Kong Gateway
      • Kong Mesh
      • Kong Ingress Controller
      • Kong Insomnia
      • Product Updates
      • Get Started
    • Documentation
      • Kong Konnect Docs
      • Kong Gateway Docs
      • Kong Mesh Docs
      • Kong Insomnia Docs
      • Kong Konnect Plugin Hub
    • Open Source
      • Kong Gateway
      • Kuma
      • Insomnia
      • Kong Community
    • Company
      • About Kong
      • Customers
      • Careers
      • Press
      • Events
      • Contact
  • Terms• Privacy• Trust and Compliance
© Kong Inc. 2025