From c90a9992f73deb3a48a734a720f9c913963a00f8 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Wed, 18 Mar 2026 16:20:41 -0400 Subject: [PATCH 1/3] [Resource Sharing] Using custom action prefixes for sample resource plugin Signed-off-by: Craig Perkins --- .../org/opensearch/sample/resource/TestUtils.java | 7 +++---- .../resource/feature/enabled/DryRunAccessTests.java | 8 ++++---- .../actions/rest/create/CreateResourceAction.java | 2 +- .../actions/rest/create/UpdateResourceAction.java | 2 +- .../actions/rest/delete/DeleteResourceAction.java | 2 +- .../resource/actions/rest/get/GetResourceAction.java | 2 +- .../actions/rest/search/SearchResourceAction.java | 2 +- .../rest/create/CreateResourceGroupAction.java | 2 +- .../rest/create/UpdateResourceGroupAction.java | 2 +- .../rest/delete/DeleteResourceGroupAction.java | 2 +- .../actions/rest/get/GetResourceGroupAction.java | 2 +- .../rest/search/SearchResourceGroupAction.java | 2 +- .../src/main/resources/resource-action-groups.yml | 12 ++++++------ .../security/privileges/PrivilegesEvaluatorImpl.java | 3 ++- 14 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java index 242fd238ad..5652673c35 100644 --- a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java +++ b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java @@ -65,10 +65,9 @@ public final class TestUtils { "resource_sharing_test_user_Limited_Perms" ).roles( new TestSecurityConfig.Role("shared_role_limited_perms").clusterPermissions( - "cluster:admin/sample-resource-plugin/get", - "cluster:admin/sample-resource-plugin/search", - "cluster:admin/sample-resource-plugin/create", - "cluster:admin/security/resource/share", + "sampleresource:get", + "sampleresource:search", + "sampleresource:create", "cluster:admin/security/resource/share" ).indexPermissions("indices:data/read*").on(RESOURCE_INDEX_NAME) ); diff --git a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/feature/enabled/DryRunAccessTests.java b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/feature/enabled/DryRunAccessTests.java index 3fa0b94af7..dcc5f54b4b 100644 --- a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/feature/enabled/DryRunAccessTests.java +++ b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/feature/enabled/DryRunAccessTests.java @@ -100,12 +100,12 @@ public void testDryRunAccess() throws Exception { HttpResponse resp = client.putJson(SAMPLE_RESOURCE_CREATE_ENDPOINT + "?perform_permission_check=true", sample); resp.assertStatusCode(HttpStatus.SC_OK); assertThat(resp.bodyAsMap().get("accessAllowed"), equalTo(false)); - assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("cluster:admin/sample-resource-plugin/create"))); + assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("sampleresource:create"))); resp = client.get(SAMPLE_RESOURCE_GET_ENDPOINT + "/" + adminResId + "?perform_permission_check=true"); resp.assertStatusCode(HttpStatus.SC_OK); assertThat(resp.bodyAsMap().get("accessAllowed"), equalTo(false)); - assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("cluster:admin/sample-resource-plugin/get"))); + assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("sampleresource:get"))); } // share resource at readonly level with no_access_user @@ -123,7 +123,7 @@ public void testDryRunAccess() throws Exception { resp = client.postJson(SAMPLE_RESOURCE_UPDATE_ENDPOINT + "/" + adminResId + "?perform_permission_check=true", updatePayload); resp.assertStatusCode(HttpStatus.SC_OK); assertThat(resp.bodyAsMap().get("accessAllowed"), equalTo(false)); - assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("cluster:admin/sample-resource-plugin/update"))); + assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("sampleresource:update"))); // cannot share resource resp = client.putJson( @@ -148,7 +148,7 @@ public void testDryRunAccess() throws Exception { resp = client.delete(SAMPLE_RESOURCE_DELETE_ENDPOINT + "/" + adminResId + "?perform_permission_check=true"); resp.assertStatusCode(HttpStatus.SC_OK); assertThat(resp.bodyAsMap().get("accessAllowed"), equalTo(false)); - assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("cluster:admin/sample-resource-plugin/delete"))); + assertThat(resp.bodyAsMap().get("missingPrivileges"), equalTo(List.of("sampleresource:delete"))); } // share resource at full-access level with no_access_user diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/CreateResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/CreateResourceAction.java index 3e73b95f79..53da66edd0 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/CreateResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/CreateResourceAction.java @@ -21,7 +21,7 @@ public class CreateResourceAction extends ActionType { /** * Create sample resource action name */ - public static final String NAME = "cluster:admin/sample-resource-plugin/create"; + public static final String NAME = "sampleresource:create"; private CreateResourceAction() { super(NAME, CreateResourceResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/UpdateResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/UpdateResourceAction.java index ec5f84adfb..b30b77b026 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/UpdateResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/create/UpdateResourceAction.java @@ -21,7 +21,7 @@ public class UpdateResourceAction extends ActionType { /** * Update sample resource action name */ - public static final String NAME = "cluster:admin/sample-resource-plugin/update"; + public static final String NAME = "sampleresource:update"; private UpdateResourceAction() { super(NAME, CreateResourceResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/delete/DeleteResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/delete/DeleteResourceAction.java index d7410e6388..180bcca277 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/delete/DeleteResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/delete/DeleteResourceAction.java @@ -21,7 +21,7 @@ public class DeleteResourceAction extends ActionType { /** * Delete sample resource action name */ - public static final String NAME = "cluster:admin/sample-resource-plugin/delete"; + public static final String NAME = "sampleresource:delete"; private DeleteResourceAction() { super(NAME, DeleteResourceResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/get/GetResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/get/GetResourceAction.java index 0249a06501..645c295383 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/get/GetResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/get/GetResourceAction.java @@ -21,7 +21,7 @@ public class GetResourceAction extends ActionType { /** * Get sample resource action name */ - public static final String NAME = "cluster:admin/sample-resource-plugin/get"; + public static final String NAME = "sampleresource:get"; private GetResourceAction() { super(NAME, GetResourceResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/search/SearchResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/search/SearchResourceAction.java index ef139938a8..407e99e3ab 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/search/SearchResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resource/actions/rest/search/SearchResourceAction.java @@ -18,7 +18,7 @@ public class SearchResourceAction extends ActionType { public static final SearchResourceAction INSTANCE = new SearchResourceAction(); - public static final String NAME = "cluster:admin/sample-resource-plugin/search"; + public static final String NAME = "sampleresource:search"; private SearchResourceAction() { super(NAME, SearchResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/create/CreateResourceGroupAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/create/CreateResourceGroupAction.java index a5eba1cea5..7ec8a8ab33 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/create/CreateResourceGroupAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/create/CreateResourceGroupAction.java @@ -21,7 +21,7 @@ public class CreateResourceGroupAction extends ActionType /** * Get sample resource group action name */ - public static final String NAME = "cluster:admin/sample-resource-plugin/group/get"; + public static final String NAME = "sampleresourcegroup:get"; private GetResourceGroupAction() { super(NAME, GetResourceGroupResponse::new); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/search/SearchResourceGroupAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/search/SearchResourceGroupAction.java index 8b0a2c6b37..66f4b54a01 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/search/SearchResourceGroupAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/resourcegroup/actions/rest/search/SearchResourceGroupAction.java @@ -18,7 +18,7 @@ public class SearchResourceGroupAction extends ActionType { public static final SearchResourceGroupAction INSTANCE = new SearchResourceGroupAction(); - public static final String NAME = "cluster:admin/sample-resource-plugin/group/search"; + public static final String NAME = "sampleresourcegroup:search"; private SearchResourceGroupAction() { super(NAME, SearchResponse::new); diff --git a/sample-resource-plugin/src/main/resources/resource-action-groups.yml b/sample-resource-plugin/src/main/resources/resource-action-groups.yml index c373634be9..4621fe78d1 100644 --- a/sample-resource-plugin/src/main/resources/resource-action-groups.yml +++ b/sample-resource-plugin/src/main/resources/resource-action-groups.yml @@ -2,26 +2,26 @@ resource_types: sample-resource: sample_read_only: allowed_actions: - - "cluster:admin/sample-resource-plugin/get" + - "sampleresource:get" sample_read_write: allowed_actions: - - "cluster:admin/sample-resource-plugin/*" + - "sampleresource:*" sample_full_access: allowed_actions: - - "cluster:admin/sample-resource-plugin/*" + - "sampleresource:*" - "cluster:admin/security/resource/share" sample-resource-group: sample_group_read_only: allowed_actions: - - "cluster:admin/sample-resource-plugin/group/get" + - "sampleresourcegroup:get" sample_group_read_write: allowed_actions: - - "cluster:admin/sample-resource-plugin/group/*" + - "sampleresourcegroup:*" sample_group_full_access: allowed_actions: - - "cluster:admin/sample-resource-plugin/group/*" + - "sampleresourcegroup:*" - "cluster:admin/security/resource/share" diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorImpl.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorImpl.java index 558fb6e6ad..1ae575f7f5 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorImpl.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorImpl.java @@ -604,7 +604,8 @@ public static boolean isClusterPerm(String action0) { || (action0.startsWith(MultiSearchAction.NAME)) || (action0.equals(MultiTermVectorsAction.NAME)) || (action0.equals(ReindexAction.NAME)) - || (action0.equals(RenderSearchTemplateAction.NAME))); + || (action0.equals(RenderSearchTemplateAction.NAME)) + || !action0.startsWith("indices:")); } private boolean checkFilteredAliases(Resolved requestedResolved, String action, boolean isDebugEnabled) { From 86f4fd6b78398437404750e4aefce61ca0873e8e Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Wed, 18 Mar 2026 16:23:00 -0400 Subject: [PATCH 2/3] Add to CHANGELOG Signed-off-by: Craig Perkins --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d5c99b13..b2b7f4ce22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Hardens input validation for resource sharing APIs ([#5831](https://github.com/opensearch-project/security/pull/5831) - Optimize getFieldFilter to only return a predicate when index has FLS restrictions for user ([#5777](https://github.com/opensearch-project/security/pull/5777)) - Make encryption_key optional for obo token authenticator ([#6017](https://github.com/opensearch-project/security/pull/6017) +- [Resource Sharing] Using custom action prefixes for sample resource plugin ([#6020](https://github.com/opensearch-project/security/pull/6020) ### Bug Fixes - Fix audit log writing errors for rollover-enabled alias indices ([#5878](https://github.com/opensearch-project/security/pull/5878) From 6d97812842144e6bfaf0092baddba77367682828 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Tue, 24 Mar 2026 11:23:17 -0400 Subject: [PATCH 3/3] Fix access levels Signed-off-by: Craig Perkins --- .../src/main/resources/resource-access-levels.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sample-resource-plugin/src/main/resources/resource-access-levels.yml b/sample-resource-plugin/src/main/resources/resource-access-levels.yml index 38f79b444f..c3d7af2c66 100644 --- a/sample-resource-plugin/src/main/resources/resource-access-levels.yml +++ b/sample-resource-plugin/src/main/resources/resource-access-levels.yml @@ -19,12 +19,21 @@ resource_types: allowed_actions: # TODO: can sample-resource access levels be referenced here? i.e. sample_read_only - "sampleresourcegroup:get" + # group read-only also grants read on child resources + - "sampleresource:get" + - "sampleresource:search" sample_group_read_write: allowed_actions: - "sampleresourcegroup:*" + # group read-write also grants read/write on child resources + - "sampleresource:get" + - "sampleresource:search" + - "sampleresource:update" sample_group_full_access: allowed_actions: - "sampleresourcegroup:*" + # group full-access grants full access on child resources + - "sampleresource:*" - "cluster:admin/security/resource/share"