{
  "id": "manage-roles",
  "title": "Manage roles",
  "url": "https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-roles/",
  "summary": "Create RedisEnterpriseRole and RedisEnterpriseClusterRole resources to grant Redis Software permissions on Kubernetes.",
  "tags": [
    "docs",
    "operate",
    "kubernetes"
  ],
  "last_updated": "2026-07-24T10:52:10-07:00",
  "page_type": "content",
  "content_hash": "8f0da59df30da3896d5e0bf042a9e9a0d9a4a6cd89b82f3ee5e6feccf2a1418e",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "A role defines a reusable set of Redis Software permissions — Cluster Manager and API access, Redis data-path access, or both — that you grant to users by creating a binding. Redis Software for Kubernetes supports two role kinds, one scoped to one or more databases, the other scoped to the entire cluster:\n\n- `RedisEnterpriseRole` — applies to one or more REDBs selected by `spec.scopes`. Use when you want to grant access to a specific database or set of databases.\n- `RedisEnterpriseClusterRole` — applies cluster-wide, across every REDB. Use for administrative access or for permissions you want everywhere.\n\nFor details on how roles and bindings work together, see [Roles and bindings](https://redis.io/docs/latest/operate/kubernetes/security/access-control/_index#roles-and-bindings). To assign a role to a user, see [Manage role bindings](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-bindings)."
    },
    {
      "id": "before-you-start",
      "title": "Before you start",
      "role": "content",
      "text": "- Requires Redis Software for Kubernetes operator 8.2.0-12 or later.\n- The role resource must live in the operator namespace. Database scopes resolve to REDBs in that namespace.\n- Decide whether you need [management permissions](#choose-a-management-role), [data-path permissions](#attach-an-acl), or both.\n- If the role references one or more `RedisEnterpriseACL` resources, create those first. See [Manage ACLs](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-acls)."
    },
    {
      "id": "choose-a-management-role",
      "title": "Choose a management role",
      "role": "content",
      "text": "`spec.managementRole` picks a Redis Software built-in role that controls API and Cluster Manager UI permissions. The allowed values differ by CRD:\n\n| CRD | Allowed `managementRole` values |\n| --- | --- |\n| `RedisEnterpriseRole` | `DBMember`, `DBViewer`, `None` |\n| `RedisEnterpriseClusterRole` | `Admin`, `ClusterMember`, `ClusterViewer`, `DBMember`, `DBViewer`, `UserManager`, `None` |\n\n`None` grants no management permissions and is the default when `managementRole` is omitted. For what each Redis Software role grants, see [Cluster-scoped role definitions](https://redis.io/docs/latest/operate/rs/security/access-control/create-cluster-roles) and [Database-scoped role definitions](https://redis.io/docs/latest/operate/rs/security/access-control/create-db-roles)."
    },
    {
      "id": "create-a-database-role",
      "title": "Create a database role",
      "role": "content",
      "text": "A `RedisEnterpriseRole` must reference at least one database in `spec.scopes`. Each scope picks REDBs by name or by label selector — not both."
    },
    {
      "id": "scope-a-role-by-redb-name",
      "title": "Scope a role by REDB name",
      "role": "content",
      "text": "[code example]\n\n`kind` defaults to `RedisEnterpriseDatabase` and can be omitted.\n\nTo scope a role to several databases by name, list each one as its own scope entry:\n\n[code example]\n\nThe role's `spec.acl` applies to every REDB in `spec.scopes`. If a database needs a different ACL, create a separate role for it."
    },
    {
      "id": "scope-a-role-by-label-selector",
      "title": "Scope a role by label selector",
      "role": "content",
      "text": "Use a selector when you want the role to follow a set of REDBs that share labels, rather than naming each one:\n\n[code example]\n\n`selector.matchExpressions` is also supported."
    },
    {
      "id": "scope-rules",
      "title": "Scope rules",
      "role": "content",
      "text": "- At least one entry in `spec.scopes` is required.\n- Each scope must set `name` or `selector`, not both.\n- `scopes[].kind` must be `RedisEnterpriseDatabase` or empty."
    },
    {
      "id": "create-a-cluster-role",
      "title": "Create a cluster role",
      "role": "content",
      "text": "A `RedisEnterpriseClusterRole` has no `scopes` field — it applies across every REDB in the Redis Software cluster.\n\n[code example]\n\nCommon patterns:\n\n- **Read-only operator** — `managementRole: ClusterViewer`, no ACL.\n- **Cluster admin** — `managementRole: Admin`, no ACL. Use sparingly.\n- **Cluster-wide data access** — `managementRole: None` (or omit) with an `acl`. The ACL applies to every REDB in the cluster."
    },
    {
      "id": "attach-an-acl",
      "title": "Attach an ACL",
      "role": "content",
      "text": "Both role kinds carry a single `RedisEnterpriseACL` reference in `spec.acl`. The ACL grants Redis data-path permissions (commands, key patterns, categories) to users who hold the role.\n\n[code example]\n\nRules:\n\n- `acl.kind` must be `RedisEnterpriseACL` or empty.\n- For a `RedisEnterpriseRole`, the ACL applies to every database the role's scopes select. If you need different data-path access for different databases, create a separate role for each.\n- For a `RedisEnterpriseClusterRole`, the ACL applies to every REDB in the cluster.\n\nSet `spec.managementRole` alone, `spec.acl` alone, or both. A role with neither set effectively grants nothing."
    },
    {
      "id": "update-a-role",
      "title": "Update a role",
      "role": "content",
      "text": "`kubectl apply` (or `kubectl edit`) updates the underlying Redis Software role. The operator reconciles changes to:\n\n- `managementRole` — replaces the management permission set on the Redis Software role.\n- `scopes` — re-resolves which REDBs the role attaches to. REDBs that drop out of the scope have the role's permissions removed.\n- `acl` — re-applies the data-path permissions to scoped REDBs (or cluster-wide for cluster roles).\n\n`status.observedGeneration` reaches the resource's `metadata.generation` once the update has been applied."
    },
    {
      "id": "inspect-role-status",
      "title": "Inspect role status",
      "role": "content",
      "text": "The `status` block is intentionally minimal:\n\n| Field | Meaning |\n| --- | --- |\n| `uid` | Internal Redis Software role UID. Present once the role has reconciled successfully. A role must have a `uid` before it can contribute permissions to any database. |\n| `observedGeneration` | The `metadata.generation` the operator last acted on. Compare with `metadata.generation` to confirm the latest spec has been processed. |\n\nTo see which users currently hold the role, list bindings that reference it:\n\n[code example]\n\nFor cluster roles, replace `redisenterpriserolebinding` with `redisenterpriseclusterrolebinding`."
    },
    {
      "id": "delete-a-role",
      "title": "Delete a role",
      "role": "content",
      "text": "Delete any bindings that reference the role first, then delete the role. Find the bindings with the recipes in [Find bindings that reference a role or user](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-bindings#find-bindings-that-reference-a-role-or-user), delete each by name, then delete the role:\n\n[code example]\n\nIf a binding still references the role at the moment of deletion, Redis Software may reject the delete and the operator emits a `RoleDeletionBlocked` event. Resolve the blocking binding and retry."
    },
    {
      "id": "troubleshoot",
      "title": "Troubleshoot",
      "role": "errors",
      "text": "Watch reconciliation events with `kubectl describe redisenterpriserole <name>` (or `redisenterpriseclusterrole`). Common issues:\n\n- **`status.uid` is empty** — The role hasn't reconciled. Check the events. Common causes: an ACL reference points to a non-existent `RedisEnterpriseACL`, or admission rejected the spec (missing scopes, scope with both `name` and `selector`, wrong `kind`).\n- **Scope selector matches nothing** — A label-selector scope is valid even if no REDB currently matches. The role contributes permissions only to REDBs that match at reconcile time. Add the labels or fix the selector.\n- **Permissions don't reach the database** — Check `status.uid` on the role, the matching REDB's `status.rolesPermissions`, and confirm a binding assigns the role to the user.\n- **`RoleDeletionBlocked`** — A binding still references the role in Redis Software. Delete the binding first.\n\nFor full field details, see the [`RedisEnterpriseRole`](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_role_api) and [`RedisEnterpriseClusterRole`](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_cluster_role_api) API reference."
    },
    {
      "id": "related-topics",
      "title": "Related topics",
      "role": "related",
      "text": "- [Roles and bindings](https://redis.io/docs/latest/operate/kubernetes/security/access-control/_index#roles-and-bindings) — the conceptual model.\n- [Manage role bindings](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-bindings) — assign a role to a user.\n- [Manage ACLs](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-acls) — define the data-path permissions a role references.\n- [Manage users](https://redis.io/docs/latest/operate/kubernetes/security/access-control/manage-users) — create the users that bindings target.\n- [Migrate from REDB rolesPermissions](https://redis.io/docs/latest/operate/kubernetes/security/access-control/migrate-rolespermissions) — move from the deprecated `RedisEnterpriseDatabase.spec.rolesPermissions` field to the new CRD model."
    }
  ],
  "examples": [
    {
      "id": "scope-a-role-by-redb-name-ex0",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1alpha1\nkind: RedisEnterpriseRole\nmetadata:\n  name: orders-viewer\nspec:\n  managementRole: DBViewer\n  scopes:\n  - kind: RedisEnterpriseDatabase\n    name: orders\n  acl:\n    kind: RedisEnterpriseACL\n    name: read-only",
      "section_id": "scope-a-role-by-redb-name"
    },
    {
      "id": "scope-a-role-by-redb-name-ex1",
      "language": "yaml",
      "code": "spec:\n  managementRole: DBViewer\n  scopes:\n  - name: orders\n  - name: customers\n  - name: inventory\n  acl:\n    name: read-only",
      "section_id": "scope-a-role-by-redb-name"
    },
    {
      "id": "scope-a-role-by-label-selector-ex0",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1alpha1\nkind: RedisEnterpriseRole\nmetadata:\n  name: prod-db-viewer\nspec:\n  managementRole: DBViewer\n  scopes:\n  - selector:\n      matchLabels:\n        environment: production\n  acl:\n    name: read-only",
      "section_id": "scope-a-role-by-label-selector"
    },
    {
      "id": "create-a-cluster-role-ex0",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1alpha1\nkind: RedisEnterpriseClusterRole\nmetadata:\n  name: support-readonly\nspec:\n  managementRole: ClusterViewer\n  acl:\n    name: read-only",
      "section_id": "create-a-cluster-role"
    },
    {
      "id": "attach-an-acl-ex0",
      "language": "yaml",
      "code": "spec:\n  acl:\n    kind: RedisEnterpriseACL\n    name: read-only    # kind defaults to RedisEnterpriseACL and can be omitted",
      "section_id": "attach-an-acl"
    },
    {
      "id": "inspect-role-status-ex0",
      "language": "sh",
      "code": "kubectl get redisenterpriserolebinding -o yaml | \\\n  yq '.items[] | select(.spec.roleRef.name == \"orders-viewer\")'",
      "section_id": "inspect-role-status"
    },
    {
      "id": "delete-a-role-ex0",
      "language": "sh",
      "code": "kubectl delete redisenterpriserolebinding alice-orders-viewer\nkubectl delete redisenterpriserole orders-viewer",
      "section_id": "delete-a-role"
    }
  ]
}
