Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: design fine grained access control rule engine #1790

Merged
merged 15 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
---
id: fine-grained-access-control
title: Fine-Grained Access Control in Design
sidebar_label: Fine-Grained Access Control
---

# Fine-Grained Access Control in Design

:::info
This feature is currently available exclusively as a **Closed Preview** and is not yet generally available. For more information and to request its activation for your Company, please contact your Mia-Platform referent.
:::

This feature introduces a mechanism for managing user interactions within the application by restricting specific actions based on user roles and specified rules in the Design section.

If a user attempts to save a configuration after performing some changes that are forbidden by the configured rules, the saving is blocked and an error is returned.

*Rules* and *user roles* can be configured at both the Project and the Company levels.
The following logic is applied:

- **Rules**: Project and Company rules are combined together without conflict, as only disallow rules are used.
- **User Roles**: If a user has roles assigned at the Project level, only those roles used to find the applicable rules. If no Project-level roles are assigned, the roles defined at the Company level are used instead.

## Configuration definition

To enable this feature the `Project` or `Company` `configurationManagement.saveChangesRules` field of the configuration must be set with a list of objects with the following structure:

| Field | Type | Description | Optional |
| ------------------- | ----------- | --------------------------------------------- | -------- |
| `disallowedRuleSet` | `RuleSet[]` | list of rules that prohibit a specific action | ❌ |
| `roleIds` | `String[]` | List of user roles to which the rules apply | ❌ |

The `RuleSet` object has these fields:

| Field | Type | Description | Optional |
| ------------------- | ------------------ | --------------------------------------------------------------- | -------- |
| `jsonPath` | `String` | JSONPath of the resource on which the action must be prevented. | ✅ |
| `processingOptions` | `ProcessingOption` | Additional options of the rule | ✅ |
| `ruleId` | `String` | Reference a to a rule from a predefined set | ✅ |

___
A `disallowedRuleSet` can be configured in 3 ways:

- [Via `jsonPath`](#via-jsonpath)
- [Via `jsonPath` and `processingOptions`](#via-jsonpath-and-processingoptions)
- [Via `ruleId`](#via-ruleid)

### Via `jsonPath`

The `jsonPath` field is used to extract a target resource applying a JSONPath expression on the JSON structure of the configuration. On the extracted resource are not permitted any updates.

### Via `jsonPath` and `processingOptions`

- The `jsonPath` is used to extract the target resource.
- The `processingOptions` define the `action` (`create`, `delete`) to prevent on the resource. If the resource captured by the jsonPath are of array type, the field `primaryKey` must be specified.

The `ProcessingOption` object has the following structure:

| Field | Type | Description | Optional |
| ------------ | ---------- | ---------------------------------------------------------------------------------------------------- | -------- |
| `action` | `string[]` | Action to be prevented on the resource defined via the jsonPath. Possible values: `create`, `delete` | ❌ |
| `primaryKey` | `String` | Primary key of the resource captured by the jsonPath. Mandatory if resource is of array type | ✅ |

### Via `ruleId`

The `ruleId` references a rule from a predefined set of rules, that define a specific behavior.

**The available `ruleIds` are**:

| `ruleId` | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------- |
| `endpoints.security.edit` | block edit of the fields [`public`, `acl`, `secreted`] of `endpoints` and `routes` inside endpoints |
| | |

## Fetching and configuring rules with `miactl`

:::info
The following `miactl` commands will be introduced in version 0.16.0 of miactl, which is not yet released.
:::

```bash
miactl company rules list --company-id=my-company
miactl company rules list --company-id=my-company --project-id=my-project
miactl company rules update --company-id=my-company -f ~/my-rules.json
miactl company rules update --company-id=my-company --project-id=my-project -f ~/my-rules.json
```

Example for the file `my-rules.json`:

```json
[
{
"roleIds": ["developer"],
"disallowedRuleSet": [
{"ruleId": "endpoint.security.edit"}
]
}
]
```

:::info
For the full specifications about the commands refer to the [related miactl documentation](/cli/miactl/30_commands.md)
:::

## Configuring rules via API

### Updating rules on a Project

The API for updating the rules on a Project is defined as follows

:::caution
This API is meant for internal use and will be subject to breaking changes.
:::

#### Request

- verb: `PATCH`
- path: `/api/backend/projects/:projectId/rules`

##### Security

| Security | Check |
|-------------------------|---------------------------------|
| Authentication required | ✅ |
| RBAC permissions | console.company.details.update |

##### Body

The **body** of the request has the structure described in [Configuration definition](#configuration-definition)

### Updating rules on a Company

The API for updating the rules on a Company is defined as follows.

:::caution
This API is meant for internal use and will be subject to breaking changes.
:::

#### Request

- verb: `PATCH`
- path: `/api/backend/tenants/:tenantId/rules`

##### Security

| Security | Check |
|-------------------------|---------------------------------|
| Authentication required | ✅ |
| RBAC permissions | console.company.details.update |

##### Body

The **body** of the request the structure described in [Configuration definition](#configuration-definition)

Below are some **examples of request bodies** for the Update Rules API. The request body format is identical for both the Update Project and Update Company APIs.

- prevent edit of the `dockerImage` of all services to the role `maintainer`

```json
{
"configurationManagement": {
"saveChangesRules": [
{
"disallowedRuleSet": [
{
"jsonPath": "$.services.*.dockerImage"
},
],
"roleIds": [
"maintainer"
]
}
]
}
}
```

- prevent creation of the resource `secrets` to the role `maintainer`

```json
{
"configurationManagement": {
"saveChangesRules": [
{
"disallowedRuleSet": [
{
"jsonPath": "$.collections",
"processingOptions": {
"action": "create"
}
}
],
"roleIds": ["maintainer"]
}
]
}
}
```

- prevent the creation of a services of a specific type (`custom-resource`) to the role `maintainer`

```json
{
"configurationManagement": {
"saveChangesRules": [
{
"disallowedRuleSet": [
{
"jsonPath": "$.services.[?(@.type==\"cursom-resource\")]",
"processingOptions": { "action": "create" }
}
],
"roleIds": ["maintainer"]
}
]
}
}
```

- configure the predefined rule with `ruleId` "endpoints.security.edit" to the role `maintainer`

```json
{
"configurationManagement": {
"saveChangesRules": [
{
"disallowedRuleSet": [
{
"ruleId": "endpoints.security.edit"
}
],
"roleIds": ["maintainer"]
}
]
}
}
```
4 changes: 4 additions & 0 deletions sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,10 @@
"id": "development_suite/api-console/api-design/authorization",
"type": "doc"
},
{
"id": "development_suite/api-console/api-design/fine-grained-access-control",
"type": "doc"
},
{
"id": "development_suite/api-console/api-design/api-key",
"type": "doc"
Expand Down