# User Roles & Access Control

The Management Console implements role-based access control (RBAC) to ensure users can only access resources and perform actions permitted by their assigned roles or groups.

## Prerequisites

To enable role-based access control, you need to configure the following settings:

In the configuration:

* Set `global.authorization.enabled` to `true`
* Set `global.authentication.enabled` to `true`
* Configure OIDC settings for token validation in the `global.authentication` section
* Configure OPA authorization policies and related parameters in the `global.authorization` section
* Ensure your Okta instance has proper role/group configurations set up
* [Configure Okta Authentication](https://documentation.alluxio.io/ee-ai-en/ai-3.7/administration/overview/deployment)

### Example Configuration

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  global:
    authentication:
      enabled: true
      type: oidc
      oidc:
        jwksUri:
        jwksConfigMapName:
        jwksFilename:
        aud:
        tid:
        nbfCheck: false
        roleFieldName: roleFieldName
        groupFieldName: groupFieldName

    authorization:
      enabled: true
      type: opa
      opa:
        superAdmin:
        groupAdmin:
        allowApis:
        denyApis:
        components:
          gateway:
            configMapName:
            filenames:
              - opa_auth_policy.rego
              - opa_data.yaml
            query: data.opa_auth_policy.allow
            groups:
              # groups config for gateway
          console:
            configMapName:
            filenames:
              - opa_auth_policy.rego
              - opa_data.yaml
            query: data.opa_auth_policy.allow
            groups:  
              # groups config for console
```

**Important Notes:** Ensure your Okta instance is properly configured with the necessary groups and roles. Each user should be assigned to appropriate groups that correspond to their access level in the system.

## Configuration Parameters

### Authentication

In the `global.authentication` section, the following key parameters are available:

* **`enabled`**: Whether to enable authentication.
* **`type`**: Authentication type, currently supports `oidc`.
* **`oidc`**: OIDC configuration parameters:
  * **`jwksUri`**: JWKS endpoint URI for obtaining public keys to verify JWT tokens.
  * **`jwksConfigMapName`**: ConfigMap name containing JWKS keys (optional, choose either this or jwksUri).
  * **`jwksFilename`**: JWKS filename.
  * **`aud`**: Audience field in JWT token for verifying the target audience of the token.
  * **`tid`**: Tenant ID for token validation in multi-tenant environments.
  * **`nbfCheck`**: Whether to validate the "nbf" (not before) claim in JWT tokens. When set to `true`, the system will reject tokens that are not yet valid (current time is before the "nbf" time). When set to `false`, the "nbf" claim validation is skipped. Default is `false`.
  * **`roleFieldName`**: Field name in JWT token containing user role information.
  * **`groupFieldName`**: Field name in JWT token containing user group information.

### Authorization

In the `global.authorization` section, the following key parameters are available:

* **`enabled`**: Whether to enable authorization control.
* **`type`**: Authorization type, currently supports `opa` (Open Policy Agent).
* **`opa`**: OPA configuration parameters:
  * **`superAdmin`**: List of super administrator roles with all permissions.
  * **`groupAdmin`**: List of group administrator roles with group-level management permissions.
  * **`allowApis`**: List of API endpoints that bypass authorization checks.
  * **`denyApis`**: List of API endpoints that are explicitly denied access.
  * **`components`**: Component-level configuration:
    * **`gateway`**: Authorization configuration for gateway component:
      * **`configMapName`**: ConfigMap name containing OPA policy files.
      * **`filenames`**: List of OPA policy files (such as `opa_auth_policy.rego`, `opa_data.yaml`).
      * **`query`**: OPA query string for policy evaluation (such as `data.opa_auth_policy.allow`).
      * **`groups`**: Group permission configuration for gateway.
    * **`console`**: Authorization configuration for console component:
      * **`configMapName`**: ConfigMap name containing OPA policy files.
      * **`filenames`**: List of OPA policy files.
      * **`query`**: OPA query string for policy evaluation.
      * **`groups`**: Group permission configuration for console.

### Console Group Permission Configuration

```yaml
groups:
- group: some-group
  role:
  - some-role
  pages:
  - /some-page
  components:
  - some-component
```

The `groups` field is a list where each entry defines which pages and components are accessible to specific roles within a group. If the default permission model [described below](#default-permission-model) meets your requirements, no additional configuration is needed. However, if you want to hide certain UI elements from specific roles within a group, you can add this configuration. See [Available disallowPages Options](#available-disallowpages-options) and [Available disallowComponents Options](#available-disallowcomponents-options) for configurable options.

### Gateway Group Permission Configuration

```yaml
groups:
- group: some-group
  allow:
    pathPrefixes:
      - prefix: /some-path
        apis:
          - /some-api
  deny:
    pathPrefixes:
      - prefix: /some-path
        apis:
          - /some-api
```

The `groups` field is a list where each entry defines which resource paths a group can or cannot access. Under the `allow` section, you define resource prefixes that can be accessed by APIs. Under the `deny` section, you define resource prefixes that cannot be accessed by specific APIs.

## Default Permission Model

The system provides three predefined user types with distinct access levels:

* **Super User**: Has unrestricted access to all pages and actions within the system.
* **Admin User**: Functions as a group-level administrator with read-only access to all data, but can only modify resources within their assigned group.
* **Regular Users**: By default, these users have no access and will be redirected to a 403 Forbidden page upon login.

For more flexible access control, you can implement custom authorization rules using OPA files. See the "Custom Authorization via OPA" section for details.

## Configuration Example

The following example demonstrates how to implement a role-based access control system with the following requirements:

* User roles are determined by the `role` field in the user's token (pre-configured in Okta)
* User groups are determined by the `group` field in the user's token (pre-configured in Okta)
* Super Users have full access to all pages and actions
* Search Admins can view all pages but are restricted to mounting and loading paths prefixed with `/search` and `/related-to-search`
* Recommend Admins can view all pages but are limited to operating on resources prefixed with `/recommend`
* All other roles are denied access and redirected to a 403 Forbidden page after login

### Configuration

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  global:
    authentication:
      enabled: true
      type: oidc
      oidc:
        jwksUri: https://my-okta.okta.com/oauth2/default/v1/keys
        roleFieldName: role
        groupFieldName: group

    authorization:
      enabled: true
      type: opa
      opa:
        superAdmin: ['Super', 'SuperUser']
        groupAdmin: ['Admin', 'Team-Admin']
        allowApis: ['/api/allow/all']
        denyApis: ['/api/deny/all']
        components:
          gateway:
            groups:  
            - group: Search
              allow:
                pathPrefixes:
                  - prefix: /search
                  # If not defined, defaults to allowing all APIs with /search path
                  - prefix: /related-to-search
                    apis:
                      - /mount
                      - /load
            - group: Recommend
              allow:
                pathPrefixes:
                  - prefix: /recommend
          console:
            groups:
      #      You can leave this section empty if the default permission model is sufficient.
      #      If uncommented, Search Admin will not be able to view the mount page
      #      - group: Search
      #        role:
      #          - Admin
      #        pages:
      #          - /mount
```

## Custom Authorization via OPA

You can implement custom authorization rules by providing your own [OPA (Open Policy Agent)](https://www.openpolicyagent.org/docs/latest/) policy file (`.rego`). To use a custom policy:

1. Mount the file using a `ConfigMap`
2. List it in `filenames`
3. Set the appropriate `query`

You can examine and modify the default OPA files in the ConfigMap for both dashboard and gateway as needed.

Note: Dashboard OPA policies must return an object in the following format:

```json
{
  "disallowPages": [],
  "disallowComponents": []
}
```

The dashboard uses this response to dynamically hide pages and UI elements based on user permissions.

### Available `disallowPages` Options:

```
/monitoring/overview
/monitoring/components
/storage
/operations/preload
/operations/free
/settings/resource-management
/settings/cache-eviction
/support/snapshot
/license
/documentation
* (all pages)
```

### Available `disallowComponents` Options:

* `createMount` – "Create" button on the Mount page
* `createQuota` – "Create" button on the Quota page
* `createTTL` – "Create" button on the TTL page
* `createPriority` – "Create" button on the Priority page
* `createJob` – "Create" button on Preload and Free pages
* `*` - All components

### Example Response

If the OPA evaluation returns:

```json
{
  "disallowPages": ["/license"],
  "disallowComponents": ["createMount"]
}
```

The user will be unable to access the License page, and the "Create" button on the Mount page will be hidden.

If the OPA evaluation returns:

```json
{
  "disallowPages": ["*"],
  "disallowComponents": ["*"]
}
```

The user will be redirected to a 403 Forbidden page after login.
