> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Access Policies (ACLs)

> Define and apply fine-grained cluster access rules using Omni Access Policies and Kubernetes RBAC.

By default, any user with write permissions in Omni gets admin-level access to Kubernetes across all clusters.

[Access Policies (ACLs)](../reference/acls) let you override this behavior by defining rules that control what specific users can do on specific clusters. For example, you can give a user full access to a staging cluster while limiting them to read-only access in production.

Only users with the Omni role `Admin` can create or modify ACLs.

<Warning>
  Users with the Omni role `Operator` or above are automatically assigned the Kubernetes group `system:masters`, which grants cluster-admin access, in addition to any groups specified in an ACL. If you need strict least-privilege access inside the cluster, keep the user's Omni role at `Reader` or `None` and use ACL rules with Kubernetes group impersonation to grant specific permissions.
</Warning>

For the full `AccessPolicy` schema, including all user matching options, cluster matching options, available roles, and test structure, see the [Access Policies reference](../reference/acls).

## Create an access policy

The example below gives `support@example.com` full access to the `staging` cluster and read-only access to the `production` cluster.

```yaml theme={null}
metadata:
  namespace: default
  type: AccessPolicies.omni.sidero.dev
  id: access-policy
spec:
  rules:
    - users:
        - support@example.com
      clusters:
        - staging
      role: Operator
      kubernetes:
        impersonate:
          groups:
            - system:masters
    - users:
        - support@example.com
      clusters:
        - production
      role: Reader
      kubernetes:
        impersonate:
          groups:
            - my-app-read-only
  tests:
    - name: support engineer has full access to staging cluster
      user:
        name: support@example.com
      cluster:
        name: staging
      expected:
        role: Operator
        kubernetes:
          impersonate:
            groups:
              - system:masters
    - name: support engineer has read-only access to my-app namespace in production cluster
      user:
        name: support@example.com
      cluster:
        name: production
      expected:
        role: Reader
        kubernetes:
          impersonate:
            groups:
              - my-app-read-only
```

Apply the policy as an Omni admin:

```bash theme={null}
omnictl apply -f acl.yaml
```

If any test assertion fails, `omnictl` rejects the apply and reports which test case did not match. Fix the rule and re-apply.

## Configure Kubernetes RBAC

Assigning an Omni role through an ACL rule controls what a user can do in Omni. To control what they can do inside the Kubernetes cluster, use the `kubernetes.impersonate.groups` field to assign the user to one or more Kubernetes groups, then bind those groups to a `Role` or `ClusterRole` using Kubernetes RBAC.

The example below creates a `read-only` role in the `my-app` namespace and binds it to the `my-app-read-only` group assigned in the ACL rule above.

```yaml theme={null}
apiVersion: v1
kind: Namespace
metadata:
  name: my-app
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-only
  namespace: my-app
rules:
  - apiGroups: ["", "extensions", "apps", "batch", "autoscaling"]
    resources: ["*"]
    verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-only
  namespace: my-app
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: read-only
subjects:
  - kind: Group
    name: my-app-read-only
    apiGroup: rbac.authorization.k8s.io
```

Apply these manifests to the relevant cluster as a Kubernetes cluster admin:

```bash theme={null}
kubectl apply -f rbac.yaml
```

## Verify access

Try to access the cluster with a `kubeconfig` generated by the user `support@example.com`:

```bash theme={null}
kubectl get pods -n my-app
```

The user should be able to list pods in the `my-app` namespace because of the `Role` and `RoleBinding` created above.

Try to list pods in another namespace:

```bash theme={null}
kubectl get pod -n <other-namespace>
```

The action should be denied.

<Warning>
  If the user `support@example.com` has the Omni role `Operator` or above assigned, they will have `system:masters` role in Kubernetes as well as the `my-app-read-only` role.
  Therefore, they will still be able to list pods in all namespaces.
</Warning>
