-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Allow Plugins to request to perform cluster actions and index actions with their assigned PluginSubject and prompt on install #15778
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Craig Perkins <[email protected]>
Signed-off-by: Craig Perkins <[email protected]>
@sohami I opened this Draft PR to show how a mechanism can work for plugins to request to perform an enumerable set of transport actions within a opensearch-project/opensearch-plugins#238 (comment)' @prudhvigodithi You may be interested in this PR as well. |
❌ Gradle check result for a841f06: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
❌ Gradle check result for c12df2d: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Signed-off-by: Craig Perkins <[email protected]>
❌ Gradle check result for df6853b: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
❕ Gradle check result for df6853b: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
❌ Gradle check result for 6b64364: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Signed-off-by: Craig Perkins <[email protected]>
❌ Gradle check result for 5b8c079: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Signed-off-by: Craig Perkins <[email protected]>
@reta I'd like to bring this PR back up in the near future. I addressed the comments to read the requested perms from a file instead of having a plugin define them in code. This also changes |
❕ Gradle check result for ea1af1f: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
* @return Subject corresponding to the plugin | ||
*/ | ||
PluginSubject getPluginSubject(Plugin plugin); | ||
PluginSubject getPluginSubject(PluginInfo pluginInfo); |
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.
Why do we need to use PluginInfo
? Plugin does not need to be told what permissions it is allowed to use: it comes from its permissions policy.
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.
Its lighter-weight than Plugin and its the vehicle that carries the actions that a plugin may request to perform with its PluginSubject.
The security plugin would need these 2 pieces of information to form the PluginSubject:
- Plugin Identifier (by convention it would be the canonical class name of the plugin)
- Requested Cluster/Index Actions <- This is what this PR is introducing. f.e. The security plugin is requesting permissions to write to the security auditlog index with its pluginSubject.
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.
Got it, this is indeed the conceptual problem (at least I overlooked). I think this pull request is a bit ahead of its time, here is my reasoning:
- the core has no notion of permissions whatsoever
- as of today, this is purely and only
security
plugin feature, and - any alternative (identity?) plugin implementation would have known nothing about permissions
I still think that the idea to expose the plugin permissions is sound but we need a way to formalize the permissions first and (may be?) make core / other plugins aware of them (basically, do what we have done with Subject
etc).
Why I think that is important, when we install any plugin right now, the security policy will be enforced no matter what. With permissions, as it stands now, this is purely hint, nothing will happen if security
plugin is not installed / disabled (or any other its replacement is present).
@peternied sorry to dragging you here, but I think the subject of permissions what discussed before, right?
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.
FWIW I think presenting this information to an administrator installing a plugin empowers them with more information about what actions a plugin will perform in the cluster regardless if the security plugin is installed or not.
I left a comment here about complications of putting system index protection directly in the core. The biggest challenge with that is that operators may need to be able to perform invasive actions on system indices and do so by presenting the admin certificate which is another feature of the security plugin.
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.
JSM Permissions actually work the same way. A cluster operator is prompted with the permissions on install even if they run opensearch with JSM disabled.
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.
FWIW I think presenting this information to an administrator installing a plugin empowers them with more information about what actions a plugin will perform in the cluster regardless if the security plugin is installed or not.
This is right, and I agree with that. The question is how to do that in a way that if administrator says "Looks good" but nothing is enforced?
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.
You're right its not possible to disable outside of the tests. JSM being removed in JDK 24 is a disruptive change. lmk if I can help with review on any items.
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.
Please join the discussion #1687 (with respect to JDK-24 subject)
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.
Hey @reta, I opened a draft PR in core to add a new sandbox module for system index protection: #16695
In its current state it is a crude implementation and would need to be expanded upon to match the functionality that the security plugin provides.
I wanted to open a draft to demonstrate some of the challenges in moving system index protection to the core. Ultimately, I think it is a good idea so that they are protected regardless if the security plugin is installed and enabled.
One of the biggest challenges is generic ActionRequest -> indices() resolution in an action filter. The way this works in the security plugin is the IndexResolverReplacer.getOrReplaceAllIndices().
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.
Function.identity() | ||
); | ||
|
||
public static final Setting<Settings> INDEX_ACTIONS_SETTING = Setting.groupSetting("index.actions."); |
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.
Why do we need this explicit permission groups? Every permission is prefixed with indices:*
or cluster:*
anyway, right? The groping could be deducted from the suffixes?
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.
Oh, I think it comes from the security plugin [1], right? It certainly would make sense to keep it the same. Could we extract this logic somewhere (if it makes sense, for permissions only) so core and security
would not duplicate it?
[1] https://github.com/opensearch-project/security/blob/main/config/roles.yml
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.
Its not quite coming from the security plugin. The security plugin defines permissions like this: https://github.com/opensearch-project/security/blob/main/src/main/resources/static_config/static_roles.yml#L11-L17
all_access:
static: true
description: "Allow full access to all indices and all cluster APIs"
cluster_permissions:
- "*"
index_permissions:
- index_patterns:
- "*"
allowed_actions:
- "*"
Cluster actions would be a list of action names, but index actions need a corresponding index pattern that the actions would be applicable to. For ultimate flexibility, different index patterns may have a different set of index actions that a plugin would be permitted to perform on the target index pattern.
I figured that it might make sense to re-post a comment I wrote at opensearch-project/security#4896 (comment) OpenSearch core already contains ground works for a protection of system indices. It works like this:
See this commit for details: 5c8b066 These concepts still come from the ES times. If I understand it correctly, the goal was to replace the warning message by an error as a breaking change with a major release. IMHO, this concept makes totally sense for core. As @cwperks has pointed out, core has no safe means of authentication. What core can do is a kind of cooperative check: If a client assures that they need to perform operations on a system index, they are allowed to. If the client signals no concrete intent to operate on system index, they are not allowed to. This avoids unwanted operations in case of bugs on side of the client - be it an overly broad index pattern or a similar case. Of course, it does not provide real security. But that just takes into account the fact that core has no means to perform a secure authentication. IMHO, a good strategy would be to build on the present ground works and to complete them. That would be also useful from a code hygiene point of view, as otherwise that existing code would be there without real purpose. Relevant code pieces: OpenSearch/server/src/main/java/org/opensearch/cluster/metadata/IndexNameExpressionResolver.java Lines 359 to 378 in 57a6605
OpenSearch/server/src/main/java/org/opensearch/rest/RestController.java Lines 374 to 381 in 57a6605
OpenSearch/server/src/main/java/org/opensearch/cluster/metadata/IndexNameExpressionResolver.java Lines 767 to 774 in 57a6605
|
Description
In #14630, a new extension point was created called IdentityAwarePlugin that has a single method called
assignSubject
. The subject that is given to IdentityAwarePlugin is intended to be a replacement fortry (ThreadContext.StoredContext ctx = threadContext.stashContext() { ... }
) and ensures that the security plugin can enforce authz checks on transport actions in this privileged block. The replacement is utilizing the assigned plugin subject and instead wrapping a block withpluginSubject.runAs(() -> { ... })
which injects an identity associated with the plugin so that the Security plugin (i.e. the IdentityPlugin) can authorize the transport actions instead of allowing the plugin to operate unrestricted.This PR allows a plugin to define a
plugin-permissions.yml
file on the same level asplugin-security.policy
file that can have 2 keys: 1)cluster.actions
and 2)indices.actions
Example
This PR modifies the
plugin-cli
to prompt a cluster admin with the requested permissions. See an example below where I modified the security plugin to be anIdentityAwarePlugin
and request permission to write to thesecurity-auditlog-*
index pattern. The security plugin always needs to be able to write to this index pattern regardless of the authenticated user's permissions.In order to extract the requested actions in
plugin-cli
I had to create a new method in the PluginsService to try instantiating a plugin with empty settings.Related Issues
#15958
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.