-
Notifications
You must be signed in to change notification settings - Fork 331
[Resource Sharing] Use DLS to automatically filter sharable resources for authenticated user based on all_shared_principals
#5600
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
…le for searching Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
all_shared_principals
all_shared_principals
all_shared_principals
all_shared_principals
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5600 +/- ##
==========================================
- Coverage 72.95% 72.89% -0.07%
==========================================
Files 408 408
Lines 25314 25260 -54
Branches 3855 3861 +6
==========================================
- Hits 18469 18414 -55
- Misses 4970 4977 +7
+ Partials 1875 1869 -6
🚀 New features to boost your workflow:
|
* @param resourceIndex The index containing the resources. | ||
* @param listener The listener to be notified with the set of accessible resources. | ||
*/ | ||
void getAccessibleResourceIds(String resourceIndex, ActionListener<Set<String>> listener); |
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.
Makes sense. I'll add this back in until hierarchy is properly supported.
sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java
Outdated
Show resolved
Hide resolved
src.query(QueryBuilders.boolQuery().filter(accessQB)); | ||
return; | ||
} | ||
pluginClient.search(request, listener); |
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.
we need to update plugin-dev documentation to declare plugin as IdentityAwarePlugin.
* @param resourceIndex The index containing the resources. | ||
* @param listener The listener to be notified with the set of accessible resources. | ||
*/ | ||
void getAccessibleResourceIds(String resourceIndex, ActionListener<Set<String>> listener); |
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.
ML uses modelGroupIds to filter search for models. We need to keep this here until we support hierarchy.
dlsFlsBaseContext | ||
dlsFlsBaseContext, | ||
adminDns, | ||
resourcePluginInfo != null ? resourcePluginInfo.getResourceIndices() : null |
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.
resourcePluginInfo will never be null since we instantiate it at class-level.
src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java
Show resolved
Hide resolved
user.getRoles().forEach(r -> principals.add("role:" + r)); | ||
} | ||
|
||
// Backend roles (LDAP/SAML/etc) – adjust getter name to your version! |
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.
nit: comment :D
|
||
List<String> principals = new ArrayList<>(); | ||
principals.add("user:*"); // Convention for publicly visible | ||
principals.add("user:" + user.getName()); |
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.
add a comment here like : // owner
?
|
||
// Build a single `terms` query JSON | ||
String dlsJson = "{\"terms\":{\"all_shared_principals.keyword\":[" | ||
+ principals.stream().map(p -> "\"" + p.replace("\"", "\\\"") + "\"").collect(Collectors.joining(",")) |
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.
for my understanding why do we need .replace?
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 needed. I'm going to refactor this to use XContentBuilder for json to avoid assembling json like this.
* @param resourceIndex The resource index to check for accessible resources. | ||
* @param listener The listener to be notified with the set of accessible resource IDs. | ||
*/ | ||
public void getOwnAndSharedResourceIdsForCurrentUser(@NonNull String resourceIndex, ActionListener<Set<String>> listener) { |
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.
same as above, we need to leave this as is to support ML.
@@ -205,42 +205,6 @@ public void testHasPermission_pluginUserDenied() { | |||
verify(listener).onResponse(false); | |||
} | |||
|
|||
@Test | |||
public void testGetOwnAndSharedResources_asAdmin() { |
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.
can leave this as is to test getAccessilbeResourceIds
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
Signed-off-by: Craig Perkins <cwperx@amazon.com>
@@ -98,6 +99,7 @@ public boolean shouldEvaluate(ActionRequest request) { | |||
ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT | |||
); | |||
if (!isResourceSharingFeatureEnabled) return false; | |||
if (request instanceof GetRequest) return false; |
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.
GetRequest needs to be skipped here as that is evaluated as a cluster permission.
} | ||
|
||
@Test | ||
public void multipleRoles_multipleLevels() { |
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.
Added an addition test here for sharing with role name.
Signed-off-by: Craig Perkins <cwperx@amazon.com>
@@ -99,6 +100,7 @@ public boolean shouldEvaluate(ActionRequest request) { | |||
); | |||
if (!isResourceSharingFeatureEnabled) return false; | |||
if (!(request instanceof DocRequest docRequest)) return false; | |||
if (request instanceof GetRequest) return false; |
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.
Adding this here to handle the case where a plugin is making a GET Request to a system index using it's PluginSubject. In that case, the plugin should have permission to perform the GET, but because it wasn't being ignored here it was going through the resource access evaluation rather than the system index access evaluator.
Description
This PR builds on the change in #5596 to use DLS to filter the results behind-the-scenes so that a resource plugin only needs to search on the resource index and only get results visible to the authenticated user in the result-set.
Take an example of a resource doc with
all_shared_principals
:With the changes in this PR, if a plugin goes to search on this index (for instance as part of an API handler to list the resources or search resources), then security will apply a filter to limit the result set to resource docs that are shared with the authenticated user. That is, docs that are either owned by the authenticated user, are public (convention
user:*
) or explicitly shared with the user directly with username or one of the user's roles.An example of the DLS filter applied would be:
Enhancement
Issues Resolved
Related to: #4500
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.