-
Notifications
You must be signed in to change notification settings - Fork 504
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
Changes from 7 commits
110aaab
e30ec0e
6bb8edd
50ff4bb
76ef9af
0b2b755
75af9e6
afd3045
2f4f9b5
39efea3
40f31c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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. | ||||||
|
||||||
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies for confusion. By "this" I mean the There is no guidance as of now in defining permissions. But we can make a suggestion to have it something like: Let me know if this helps. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.