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

Add documentation for authorization on the REST layer #4544

Merged
merged 11 commits into from
Sep 29, 2023
90 changes: 90 additions & 0 deletions _security/access-control/rest-layer-authz.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
layout: default
title: REST layer authorization
parent: Access control
nav_order: 80
---


# REST layer authorization

Authorization on the REST layer provides an added level of security for plugin and extension API requests by offering a mechanism for authorization checks on the REST layer. This level of security sits atop the transport layer and provides a complementary method of authorization without replacing, modifying, or in any way changing the same process on the transport layer. REST layer authorization was initially created to address the need for an authorization check for extensions, which do not communicate on the transport layer. However, the feature is also supported for existing plugins and will be available for future plugins created to operate with OpenSearch.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Authorization on the REST layer provides an added level of security for plugin and extension API requests by offering a mechanism for authorization checks on the REST layer. This level of security sits atop the transport layer and provides a complementary method of authorization without replacing, modifying, or in any way changing the same process on the transport layer. REST layer authorization was initially created to address the need for an authorization check for extensions, which do not communicate on the transport layer. However, the feature is also supported for existing plugins and will be available for future plugins created to operate with OpenSearch.
Authorization on the REST layer provides an added level of security for plugin and extension API requests by offering a mechanism for authorization checks on the REST layer. This level of security sits atop the transport layer and provides a complementary method of authorization without replacing, modifying, or in any way changing the same process on the transport layer. REST layer authorization was initially created to address the need for an authorization check for extensions, which do not communicate on the transport layer. However, the feature is also available for developers to utilize while creating future plugins to operate with OpenSearch.

Current plugins have not been migrated to utilize this feature. But, the feature is available for current plugins to migrate their APIs to support authorization.


For users that work with REST layer authorization, the methods of assigning roles and mapping users and roles, and the general usage of plugins and extensions, remain the same: the only additional requirement being that users become familiar with a new scheme for permissions. Developers, on the other hand, will need to understand the ideas behind `NamedRoute` and how the new route scheme is constructed. For detailed information, see [Authorization at REST Layer for plugins](https://github.com/opensearch-project/security/blob/main/REST_AUTHZ_FOR_PLUGINS.md).

The benefits to developers when using the REST layer for authorization mean that they do not need to build transport layer actions and get authorization for them to adhere to security procedures. As a result, this decreases the code-writing burden and time invested in creating a single action. As an alternative, they can create REST API actions and authorize them on the REST layer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The benefits to developers when using the REST layer for authorization mean that they do not need to build transport layer actions and get authorization for them to adhere to security procedures. As a result, this decreases the code-writing burden and time invested in creating a single action. As an alternative, they can create REST API actions and authorize them on the REST layer.
The benefits to developers when using the REST layer for authorization mean that they can authorize requests at REST layer and filter out unauthorized requests. As a result, this decreases the processing burden on transport layer while allowing granular control over access to APIs.

We are not replacing transport authz, we are just adding a layer on top.


The Security plugin must be enabled to use REST layer authorization.
cwillum marked this conversation as resolved.
Show resolved Hide resolved
{: .note }


## NamedRoute

REST layer authorization provides cluster administrators with the ability to grant or revoke access to specific endpoints in a cluster. To achieve this, the route to the resource uses a unique name.

To facilitate REST layer authorization, OpenSearch introduces the idea of [`NamedRoute`](https://github.com/opensearch-project/OpenSearch/blob/main/server/src/main/java/org/opensearch/rest/NamedRoute.java) for route registration. For developers, this standard requires a new method for registering routes that utilizes a unique name. While transport actions typically consist of a method name, a part, and a corresponding transport action, this new implementation requires a method name, a part, and a unique name for the route. As the name suggests, it is essential that it be unique among all plugins and extensions or, in other words, not registered for any other route.
cwillum marked this conversation as resolved.
Show resolved Hide resolved
cwillum marked this conversation as resolved.
Show resolved Hide resolved

For example, consider the following route for an Anomaly Detection resource:

`_/detectors/<detectorId>/profile`

To create a NamedRoute from this, the `routeNamePrefix` value in the `settings.yml` file for the resource `ad` is added to the route to complete a unique name. The result is shown in the following example:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true only for extensions. For plugins, developers will have to declare the permission names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DarshitChanpura (1) What exact part of "this" is true for creating a permission name for extensions? Is it this whole piece: "... the routeNamePrefix value in the settings.yml file for the resource ad is added to the route to complete a unique name."?
(2) Is there any guidance for declaring a permission name for plugins? Are there required elements in the name like that for a permission name for an extension? Or do you just invent anything you want?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for confusion. By "this" I mean the routeNamePrefix is a setting only configured in extension. This setting doesn't exist in plugins.

There is no guidance as of now in defining permissions. But we can make a suggestion to have it something like: <plugin/extension-name>:<route> (i.e. ad:detectors/get)

Let me know if this helps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DarshitChanpura Thanks for the clarification. I've adjusted that wording to include current understanding for extensions and plugins. I've also addressed the other two comments/suggestions. I think this should be ready for documentation team review when 2.11 comes along. I'll comment that it's on hold for that. And if there are any changes between now and then, we can always revise the current draft before the release.


`ad:detectors/profile`

The route name can then be mapped to a role in the same way a traditional permission is mapped. This is demonstrated in the following example:

```yml
ad_role:
reserved: true
cluster_permissions:
- 'ad:detectors/profile'
```


## Mapping users and roles

There is no change to the way you map users and roles with `NamedRoute`. Also, the new format for the permission is compatible with existing configurations. This section provides an example of how user and role mappings look for legacy and `NamedRoute` configurations and how they authorize registered routes for actions.
cwillum marked this conversation as resolved.
Show resolved Hide resolved

When a user initiates a REST request, the user's roles are examined, and each permission associated with the user is evaluated to determine whether there is a match with the unique name assigned to the route or a match with any of the legacy actions defined during the route's registration. A user can be mapped to roles that contain permissions formatted for a unique name or a legacy action. Consider the following role for a fictional plugin `abc`:

```yml
abcplugin_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/abcplugin/route/get'
```

Also consider the following role mapping:

```yml
abcplugin_read_access:
reserved: true
users:
- "user-A"
```

If `user-A` makes a REST API call to the route `/_plugins/_abcplugin/route/get`, the user is granted authorization for the action. For a different route `/_plugins/_abcplugin/route/delete`, however, the request is denied.
cwillum marked this conversation as resolved.
Show resolved Hide resolved

The same logic holds true for roles and role mappings that use a unique name for the route and the concept of `NamedRoute`. Consider the following role for the same plugin `abc`:

```yml
abcplugin_read_access_nr:
reserved: true
cluster_permissions:
- 'abcplugin:routeGet'
- 'abcplugin:routePut'
- 'abcplugin:routeDelete'
```

Also consider the following role mapping:

```yml
abcplugin_read_access_nr:
reserved: true
users:
- "user-B"
```

In this second case, if `user-B` makes a REST API call to any of the routes `/_plugins/_abcplugin/route/get`, `/_plugins/_abcplugin/route/put`, or `/_plugins/_abcplugin/route/delete`, the user is granted authorization for the action.

2 changes: 1 addition & 1 deletion _security/access-control/users-roles.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: default
title: Users and roles
parent: Access control
nav_order: 80
nav_order: 85
redirect_from:
- /security/access-control/users-roles/
- /security-plugin/access-control/users-roles/
Expand Down