-
Notifications
You must be signed in to change notification settings - Fork 282
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
[Question] Granting Permissions to Extensions #2552
Comments
Hi @scrawfor99 , thank you for making this document with these detailed design. I do have a question on be half of the following paragraph:
My question is mainly about "how can we distinguish 'basic' permissions and 'optional' permissions". I was thinking that if an extension needs certain extra/optional permissions to accomplish their jobs, these permissions should be also considered as "basic" permissions. According to this, I think all the required permissions should be given to the extension during the installation step, and no need for adding them later. |
Hi @RyanL1997, thank you for following up. To answer your question, it should not matter whether a permission is "basic" or "optional". The distinction in the document is simply made so that it is clear when it refers to a permission granted on installation or later. I agree with you that all required permissions should be granted on installation. For optional permissions, I was more referring to permissions which would allow extra functionality or perhaps some type of metric tracking a user may not want. For instance, something like a cookie for an extension users may not want. Does that answer your question? |
Hi @opensearch-project/security, I am going to make some executive decisions to try to drive these questions to a resolution. For each of the points below, I will be moving forward unless I hear objections by Tuesday 4/4.
|
@scrawfor99 See responses below:
See example below:
See example below of roles that HelloWorld extension could like to add:
|
Closing with decisions: How do extensions get starting permissions?
How should extensions register ‘predefined’ roles?
How does an admin allow/disallow optional permissions for an extension?
How and where does the security plugin enforce extension permissions?
|
|
Problem Statement
We need to be able to configure and query the permissions an extension has.
Action items decided on this issue:
Why do we need to be able to configure permissions for extensions?
There are two main scenarios which require us to be able to manage the permissions an extension has directly.
We need to be able to restrict what an extension can do. Part of the motivation behind extensions is designing a more secure system where extensions are not granted the same type of wide-spread authorization that plugins are. In order to meet this goal, we need to be able to limit the permissions that extensions have to a target set.
We need to be able to query the granted permissions of an extension when an extension tries to execute a request. If an extension tries to read an index, we need to be able to confirm that the cluster administrator (or whoever is configuring the permissions) is alright with the extension reading that index.
What design considerations should be made?
Permission Resolution: User privileges are resolved through the permissions associated with roles and action groups. This can make it challenging to determine which permissions a user has been granted. We should avoid this pattern with extensions. If we want to allow for roles to be created and use these roles to grant permissions to extensions, that is fine. What we should avoid is relying on roles as the sole means to credit permissions to an extension. In isolated cases where an extension only has a single role, the operation of resolving the permissions will be O(n). In the majority of cases however, the operations will be O(n^2). If we instead directly assign the permissions to the extension and resolve them without the roles, we will always have O(n) matching the best case scenario of the role-based processing.
Permission Querying: It is important that we allow users to query the list of permissions which an extension has been granted. Though the list may become long, it is important for the list of permissions to be fetch-able so that users can check what permissions an extension has. This will improve user experience and also minimize the chances that a user grants permissions to an extension they do not mean to. A user will still be able to grant permissions erroneously but if they can query the permissions an extension has, it should be straightforward for them to confirm the extension has the permissions they intend.
Permission Delta: One feature that is likely to be very helpful is a permission delta preview. Basically, when a user makes a change to permissions, it would be helpful if they could see the result of that permission change either all the time or when it is a large enough change. When designing the method of granting permissions to extensions, we should keep this feature in mind.
What are the options for granting permissions to extensions?
The act of granting extensions permissions should occur in two places. First, when an extension is registered, it is likely that it will immediately require some permissions to operate. When a user installs an extension, they should then be provided with a list of all the permissions that the extension would like to be immediately granted. The user can then accept or deny this grant and the extension will not be fully installed unless they accept.
The second scenario where an extension is granted permissions should be when a user wishes to grant it access to data, resources, or additional operations. This process should occur whenever the user wants but it must occur outside of the operation of the extension. We do not want an extension to be able to begin some operation without having all the required permissions as a prerequisite. I have concerns this could potentially lead to an in-process extension locking down the cluster.
In both scenarios where a permission is granted to an extension, we should wait for all node states to be consistent before we allow operations using the extension. This will prevent any de-synchronicity issues from arising where one node is up-to-date and another is not.
It is likely that extensions will require a set of permissions in order to function at all. For instance, a database extension may require
indices:data/read/*
in order to function. As opposed to optional access permissions which can grant extensions the freedom to execute extra operations or at an expanded scope, basic access permissions are necessary to the extensions core functionality. Basic access permissions represent the necessary requirements of the extension's operation and will need to be granted to the extension upon installation.In order to grant an extension its basic access permissions, extensions will need to provide a list of them to the cluster. When an extension
Extension1
is going to be installed, it will need a mechanism to communicate its requirements to the cluster which in turn will wait for the cluster administrator to approve this grant before the extension can complete.There are two ways that an extension could specify its base access permissions.
For example:
What do code changes look like?
Currently, plugins can contain a
config
directory where they may store configuration files. When a plugin is installed and has aconfig
directory, the files are added to a subdirectory of the OpenSearch coreconfig
directory. Extension authors will just need to add a file into theconfig
directory of their extension and it should be installed into OpenSearch when they install the extension. The configuration settings will need to be applied from the installed location so a handler will need to be added that checks for updates to the coreconfig
directory and applies the changes to the cluster. This is relatively similar to how plugins work now, but needs to be made hotswappable. To make the installation hotswappable, code will also need to be added to the installation process. For instance, theInstallPluginCommand
will need to be updated to support extensions and also an API should be added so that this command can be run while the cluster is live.The response would then contain a list of the basic access requirements for the extension and the installer would either accept or decline them.
What do code changes look like?
This will require making numerous new classes in the OpenSearch core
server
directory. The classes will add the API code and the service that can update the coreconfig
file for the extension. Like the first option, code will need to be changed in theInstallPluginCommand
since the command will need to be able to be run while the cluster is live. Most changes will take place in the core code base as opposed to the Security Plugin.Given the overlap in the two options, one solution does not necessarily need to be picked over the other. It would be reasonable to start with the first option and add the second at a later date.
In the plugin model, plugins are able to register 'predefined' roles which reduce the complexity of permission assignment for the end user. Instead of an administrator needing to grant all the individual permissions a plugin introduces, they can assign the
my_plugin_full_access
role. Similarly, predefined roles such asmy_plugin_read_only
contain all the relevant permissions for read operations.Plugins converting to extensions and some native extensions will need methods of registering these predefined roles. There are two main options for handling the registration of predefined roles for extensions. The method of granting starting permissions to extensions may make this decision obvious or vice versa.
my_extension_config.yml
, extensions would include a section for the roles they would like to register upon installation.What do code changes look like?
This option is similar to what plugins do today, so fewer code changes would be required. In general, some additional logic may be required for handling the
extensions:
path in core if extensions are to be stored separately from plugins. The other area where code changes may be required is in the the Security Plugin if changes were to be made to thestatic_action_groups
etc.The API could either contain a single role as the payload and be called multiple times upon installation of the extension.
If calling the API multiple times for one role at a time an example of the API could look something like this:
If instead calling the API a single time for all roles to be added at once, an example could look something like:
What do code changes look like?
This option requires significantly more changes than the first. In order to add the API, new classes will need to be added into the
server
directory of OpenSearch core. Additionally, changes will need to be added so that the information passed via the API is added to the configuration subdirectory of the extension. The upside of this option is that many of the steps from the previous question can be repeated. There is not much difference between registering the predefined roles and reading the starting permissions outside of the execute functions on the transport layer.While an administrator has the ability to confirm or deny an extension's request for its basic access permissions, it is also likely that an installed extension will require further permissions to complete certain tasks. For example, a database extension may be able to complete basic functions with only read access. However, in order for it reorganize data it may also require write and update access.
There are two primary ways that granting optional permissions to an extension could occur. Unlike some other proposals,
these options are not expected to be compared against one another and should instead be used together.
The first way that an administrator could grant additional permissions to an extension would be directly. In a similar manner to how users are granted permissions, it make sense that a cluster administrator would want to be able to give an extension specific permissions. This process should be able to happen via an API similar to how permissions are granted to users. Instead of using roles to grant the permissions, it will likely more sense to grant the permissions individually or as part of some type of action group.
The second way that an administrator can grant permissions to an extension aims to reduce the work the administrator needs to take before the extension is fully operative. If extensions register their actions with the security plugin when they are installed, it will be possible for the security plugin to search the permissions required for an extension to execute an action. After searching the required permissions the extension will require, the security plugin should then return the permissions the extension currently lacks. The user will then be prompted to grant these permissions to the extension--assuming they are an administrator and confirmed they wanted to grant the additional permissions the extension will now have the new permissions.
What do code changes look like?
Code changes for this option depend on whether both suggested methods are implemented.
If only method 1 is implemented, the code changes will be isolated to the creation of an
Extension
object class and maybe a couple code changes in the permission granting API. When an extension is added, we will want to create a an instance of anExtension
object in core (this is a class that will need to be added) which contains metadata about the extension. Part of this metadata should be a service account name that is similar to a user account. The cluster administrator should then be able to reference the service account in a similar manner to how they would a user account name and grant permissions.If method 2 is also implemented, further code changes will be required. The extension installation process will need to be changed in core so that all of the actions that an extension may attempt to perform are mapped to the corresponding user request. For example, if
my_extension
has an actionmy_action
which performs aread
,write
, andupdate
action on a target index, the extension will need to provide this information to OpenSearch core when it is installed. This requirement would require redesign from existing plugins so would likely need to be optional. It may be possible to use thePrivilegesEvaluator
in the Security Plugin to identify the privileges that the extension has and compare those to the registered, required permissions for the target action and then prompt the administrator. This option should probably be implemented as a follow-up option.When an extension is installed, the cluster administrator likely grants it a set of basic access permissions. Then, if the administrator wants to perform any complex actions with the extension, they probably will have to grant the extension additional permissions. With various permissions being granted, it is important that there is a clear mechanism for enforcing authorization. How should the grants be used to check whether a given action is allowed? Where should this check occur?
There are two times when it makes the most sense to check whether an extension has the required permission to perform an action.
This option makes the most sense if we do not want a request to reach the extension if it can only be partially processed. A request which cannot be completed may be concerning if the cluster has no way of ending deadlocks with extensions. For example, if the extension refuses to respond to the cluster until it completes the action but the cluster will not allow the extension to complete because it lacks the necessary permissions, you could run into a scenario where the request hangs forever. For asynchronous processes this may not be concerning but if an extension is operating in-process, then such a scenario could result in cluster failure.
In order to avoid such a scenario, the cluster should check that an extension has all the required permissions to perform a given action before the request ever reaches it. Referring to the following diagram, the cluster should verify that the extension has all relevant permissions at 4.
At 4, the cluster has not yet sent the request to the extension. Instead, the Security Plugin is able to interact with the request and verify that the permissions that the request requires have been granted to the extension. For the cluster to be able to verify that the extension has all the required permissions by step 4, the cluster would need to have a complete archive of all the permissions each of the extension's operations requires.
What do code changes look like?
In order for this change to be implemented, modifications will need to be made in OpenSearch core and the Security Plugin. This option will require OpenSearch core to register all the actions of an extension beforehand and being able to map a user request to an extension to the corresponding child actions that the extension will try to enact. This is similar to the more complicated method of granting optional permissions to an extension. A hook will also need to be added in the Security Plugin inside the
PrivilegesEvaluator
to grab the extension permissions when the user permissions are checked for the request. Alternatively the hook could be implemented into the step of token creation. This would also take part in the Security Plugin.This option does not require the cluster to know all the actions the extension will want to take in advance. The cluster can intercept the action request and confirm that the operations the extension wants to perform are allowed.
What do code changes look like?
This option is easier to implement since the request can be treated as a new sub-request. When the request reaches OpenSearch from the extension, the Security Plugin can simply extract the extension information from a token and then authorize the requests against the permission storage. The permission evaluation can be handled with minimal changes to
PrivilegesEvaluator.java
. This option should not require any changes to OpenSearch core.The text was updated successfully, but these errors were encountered: