diff --git a/_dashboards/security/resource-sharing.md b/_dashboards/security/resource-sharing.md new file mode 100644 index 0000000000..542fc00688 --- /dev/null +++ b/_dashboards/security/resource-sharing.md @@ -0,0 +1,308 @@ +--- +layout: default +title: Resource Access Management via Dashboards +nav_order: 145 +--- + +# Resource Access Management via Dashboards + +**Introduced 3.3** +{: .label .label-purple } + +Resource Sharing in OpenSearch Dashboards provides **fine-grained, document-level access control** for plugin-defined resources such as ML model groups, anomaly detectors, reports definitions, and other shareable objects. It extends OpenSearch’s role-based access control (RBAC) by allowing resource owners to specify *who* can access a resource and *what level of access* they have. + +This feature is **experimental**. +{: .warning } + +--- + +## How resource sharing works + +A **resource** is a document created by a plugin and stored in a protected system index. Examples: + +- ML model groups and models +- Anomaly detectors +- Reporting definitions +- Workflows (Flow Framework) +- Any plugin-defined resource type + +Default access: + +| User | Access | +|------------------|-----------------------------------------| +| Resource creator | Full access (view, edit, delete, share) | +| Super-admin | Full access | +| Other users | No access unless shared | + +Once a resource is shared with specific users, roles, or backend roles, it becomes visible to those users inside Dashboards. Dashboards automatically filters resource lists based on your identity, permissions, and the resource sharing configuration. + +--- + +# Requirements + +To use resource sharing in Dashboards, you must have: + +### 1. Plugin-level cluster permissions +These are assigned by an administrator. Required for resource creation. + +### 2. Resource-level sharing access +A resource must be shared with you explicitly unless you are the owner or a super-admin. + +### 3. Security plugin settings enabled + +Admins must enable: + +```yaml +plugins.security.experimental.resource_sharing.enabled: true +plugins.security.experimental.resource_sharing.protected_types: [""] +plugins.security.system_indices.enabled: true +```` + +If you do not see sharing options in Dashboards, contact your administrator. +{: .note } + +--- + +# Sharing resources through the Dashboards UI + +On left-hand navigation page, under Management section `Resource Access Management` app must be visible if the resource-sharing feature is enabled. + +## 1. Open a shareable resource + +Click on `Resource Access Management` app. Once the page loads, you will see a drop-down with a label `Select a type...`. + +Select a resource type that you would like to see your accessible resources for. + +## 2. Open the Sharing panel + +Once you select an available resource type, the Resources table will be populated will all resources you have access to. If you do not see any resources, create one or ask admins or resource owners to share them with you. + + +## 3. Choose an access level + +Dashboards retrieves available access levels (action groups) dynamically from OpenSearch. Examples: +* `ad_read_only` +* `ml_read_write` +* `flow_framework_full_access` + +NOTE: These access levels are plugin-specific levels and vary by resource-type. +{: .note } blue + +Choose the level and proceed to next step. + +## 4. Add users, roles, or backend roles + +You can grant access to: + +* Specific users +* Specific roles +* Specific backend roles + +Example inputs: + +* User: `alice` +* Role: `data_viewer` +* Backend role: `engineering_team` + +Wildcards (`*`) are supported and come into effect only for users field which can be used to mark a resource as a publicly accessible at the chosen access level. + +## 5. Save your changes + +Dashboards updates the backend configuration and immediately applies access changes. + +--- + +# Viewing and managing access + +The Sharing panel shows: + +* The **resource owner** +* All users/roles/backend roles with access +* Their access levels +* Whether you can reshare the resource + +A user can share a resource only if: + +* They are the owner +* Or the owner shared the resource with them *and* granted share permission +* Or they are a super-admin + +Removing access immediately hides the resource from affected users. + +--- + +# Listing resources shared with you + +Dashboards automatically displays only the resources you can access. No special actions are required. Visibility is determined by: + +* Ownership +* Sharing configuration +* Plugin cluster permissions +* Role/backend role membership +* Wildcards (`users: ["*"]` for public resources) + +--- + +# Managing resource sharing using Dev Tools + +You can also manage resource sharing directly using the **Dev Tools Console** in Dashboards. These operations can only be performed if you are the owner, a super-admin or have sharing access to the resource. + +All APIs start with: + +``` +_plugins/_security/api/resource +``` + +--- + +## 1. Migration API (admin-only) + +Used once to import legacy plugin-managed sharing metadata. + +``` +POST _plugins/_security/api/resources/migrate +{ + "source_index": "", + "username_path": "", # e.g. /owner/name + "backend_roles_path": "", # e.g. /owner/backend_roles + "default_owner": "some_user", + "default_access_level": { + "": "" # if resource-index has more than one resource type add more entries + } +} + +``` +{% include copy-curl.html %} + +## 2. View sharing configuration + +``` +GET _plugins/_security/api/resource/share?resource_id=&resource_type= +``` +{% include copy-curl.html %} + +--- + +## 3. Share a resource (replace all access) + +This **overwrites** the entire sharing configuration. + +``` +PUT _plugins/_security/api/resource/share +{ + "resource_id": "model-group-123", + "resource_type": "ml-model-group", + "share_with": { + "read_only": { "users": ["bob"] }, + "read_write": { "users": ["charlie"] } + } +} +``` +{% include copy-curl.html %} + +--- + +## 4. Add or revoke access (non-destructive) + +This updates sharing without removing existing access. + +``` +PATCH _plugins/_security/api/resource/share +{ + "resource_id": "model-group-123", + "resource_type": "ml-model-group", + + "add": { + "read_only": { "users": ["dave"] } + }, + + "revoke": { + "read_write": { "users": ["charlie"] } + } +} +``` +{% include copy-curl.html %} + +--- + +## 5. List all resources you can access + +``` +GET _plugins/_security/api/resource/list?resource_type= +``` +{% include copy-curl.html %} + +--- + +## 6. List all shareable resource types + +``` +GET _plugins/_security/api/resource/types +``` +{% include copy-curl.html %} + +Dashboards uses this to determine supported access levels per resource type. + +--- + +## 7. Making a resource public + +``` +PATCH _plugins/_security/api/resource/share +{ + "resource_id": "model-group-123", + "resource_type": "ml-model-group", + "add": { + "read_only": { "users": ["*"] } + } +} +``` +{% include copy-curl.html %} + +--- + +## 8. Making a resource private + +``` +PUT _plugins/_security/api/resource/share +{ + "resource_id": "model-group-123", + "resource_type": "ml-model-group", + "share_with": {} +} +``` +{% include copy-curl.html %} + +This resets the resource to **owner-only**. + +--- + +# Troubleshooting + +| Issue | Possible cause | Fix | +|----------------------------------------------|----------------------------------------|----------------------------------------------------------------------------| +| `Resource Access Management` app not visible | Feature disabled | Ask admin to enable `resource_sharing.enabled` | +| User can't create resource | Missing plugin API permissions | Ask admin to map to appropriate role | +| User can't access a resource | Resource is not shared with them | Ask owner to share it with them at appropriate access level | +| API returns 403 in Dev Tools | Resource is not shared with them | Ask owner to share it with them at appropriate access level | +| Resource not listed in Dashboards | Resource not marked as protected | Ask admin to mark resource as protected `resource_sharing.protected_types` | +| PATCH does nothing | Access level not defined for that type | Verify plugin’s action-groups | + +--- + +# Summary + +Resource Sharing in Dashboards allows you to: + +* Keep resources private +* Share resources securely with specific users or teams +* Grant read-only or read-write access +* Modify or revoke access at any time +* Automate or batch operations using Dev Tools + +Dashboards provides a simple UI for everyday access management, while Dev Tools offers full control for advanced workflows. + +If resource sharing features are not visible in Dashboards, contact your OpenSearch administrator to enable the capability and assign appropriate permissions. + +Looking for backend concepts, APIs, and YAML setup? See the backend guide: [Resource Sharing and Access Control]({{site.url}}{{site.baseurl}}/security/access-control/resources/) +{: .note} diff --git a/_security/access-control/resources.md b/_security/access-control/resources.md new file mode 100644 index 0000000000..62d336fe4c --- /dev/null +++ b/_security/access-control/resources.md @@ -0,0 +1,374 @@ +--- +layout: default +title: Sharing resources between access roles +parent: Access control +nav_order: 130 +--- + +# Resource Sharing and Access Control + +**Introduced 3.3** +{: .label .label-purple } + +This feature is **experimental**. +{: .warning } + +The **Resource Sharing and Access Control** framework in the OpenSearch Security plugin provides *document-level*, fine-grained access management for plugin-defined resources. It extends OpenSearch’s existing role-based access control (RBAC) by letting resource owners explicitly share individual resources with other principals. + +With this feature, you can: + +- Share or revoke access to your resources. +- Allow users with share permission to redistribute access. +- View and manage all shareable resources as a super administrator. +- Integrate shareable resource types through a standardized **Resource Sharing SPI**. +- Search resource indices with automatic per-user filtering applied by the Security plugin. + +A **resource** is currently defined as a **document stored in a plugin’s system index**, and sharing information is stored in a **central security-managed system index**. + +--- + +# Enabling resource sharing + +The feature is controlled through the cluster settings configuration. + +## Cluster settings + +To enable resource sharing: + +```yaml +plugins.security.experimental.resource_sharing.enabled: true +plugins.security.system_indices.enabled: true +``` +{% include copy.html %} + +### Protected resource types + +Administrators must list which resource types use resource-level authorization: + +```yaml +plugins.security.experimental.resource_sharing.protected_types: ["sample-resource", "ml-model"] +``` +{% include copy.html %} + +These types must match the resource types declared by plugins implementing the `ResourceSharingExtension` SPI. + +### Dynamic updates (3.4+) + +Starting with **3.4**, both settings can be updated dynamically: + +``` +PUT _cluster/settings +{ + "transient": { + "plugins.security.experimental.resource_sharing.enabled": true, + "plugins.security.experimental.resource_sharing.protected_types": ["sample-resource"] + } +} +``` +{% include copy-curl.html %} + +In **3.3**, these settings can be updated **only through `opensearch.yml`** and require a restart. + +--- + +# Required permissions + +Resource sharing requires plugin-specific cluster permissions. Add the following to `roles.yml`: + +```yaml +sample_full_access: + cluster_permissions: + - 'cluster:admin/sample-resource-plugin/*' + +sample_read_access: + cluster_permissions: + - 'cluster:admin/sample-resource-plugin/get' +``` +{% include copy.html %} + +Users must have both: + +1. Cluster permissions for the plugin APIs +2. Resources shared with them through the sharing APIs + +Sharing alone does **not** grant API access. + +--- + +# Resource sharing components + +The resource sharing framework includes several internal components and APIs. + +## Service Provider Interface (SPI) + +Plugins integrate through the **`opensearch-security-spi`** package. + +Plugins must implement: + +* `ResourceSharingExtension` + Declares shareable resource types and system indices. +* `ResourceSharingClientAccessor` + Provides access to verification, sharing, and listing operations. + +Plugins must also register: + +``` +src/main/resources/META-INF/services/org.opensearch.security.spi.ResourceSharingExtension +``` + +Containing only: + +``` +com.example.MyResourceSharingExtension +``` + +{% include copy.html %} + +## resource-action-groups.yml + +Plugins define access levels using action groups: + +```yaml +resource_types: + sample-resource: + sample_read_only: + allowed_actions: + - "cluster:admin/sample-resource-plugin/get" + + sample_read_write: + allowed_actions: + - "cluster:admin/sample-resource-plugin/*" +``` + +These action groups become the valid “access levels” a user may share. + +--- + +# Data model + +All sharing metadata is stored in a dedicated *security-owned* system index. + +| Field | Description | +|---------------|------------------------------------------------| +| `resource_id` | Unique identifier of the resource | +| `created_by` | Creator username (and tenant if applicable) | +| `share_with` | Mapping of action-groups to allowed principals | +| `source_idx` | Resource index managed by the plugin | + +### Example document + +```json +{ + "resource_id": "model-group-123", + "created_by": { + "user": "darshit", + "tenant": "analytics" + }, + "share_with": { + "read_only": { + "users": ["alice"], + "roles": ["data_viewer"], + "backend_roles": ["analytics_backend"] + } + } +} +``` + +To make a resource public: + +```json +{ + "share_with": { + "read_only": { + "users": ["*"] + } + } +} +``` +NOTE: Resource will be marked public only if "*" is added to user list. +{: .note} yellow + +To keep a resource private: + +```json +{ "share_with": {} } +``` + +--- + +# Access filtering for plugins + +When plugins perform a search on their system index: + +* The plugin performs the search using its system identity +* Security automatically filters documents based on: + + * resource owner + * shared principals + * privileges + +For example, only documents whose `all_shared_principals` list matches the authenticated user or roles will be returned. + +This filtering is done automatically if the plugin: + +* Implements `IdentityAwarePlugin` +* Uses system identity for index access (no `stashContext`) + +--- + +# Java APIs for plugins + +Plugins call the ResourceSharingClient to enforce access. + +### Verify resource access + +``` +client.verifyAccess(resourceId, resourceIndex, action, listener); +``` + +### List accessible resource IDs + +``` +client.getAccessibleResourceIds(resourceIndex, listener); +``` + +### Check if feature enabled for type + +``` +client.isFeatureEnabledForType(resourceType); +``` + +--- + +# REST APIs + +## 1. Share a resource + +Replace the entire sharing configuration. + +``` +PUT _plugins/_security/api/resource/share +{ + "resource_id": "123", + "resource_type": "sample-resource", + "share_with": { + "read_only": { + "users": ["alice"], + "roles": ["auditor"] + } + } +} +``` +{% include copy-curl.html %} + +--- + +## 2. Modify sharing configuration + +Add or revoke access. + +``` +PATCH/POST _plugins/_security/api/resource/share +{ + "resource_id": "123", + "resource_type": "sample-resource", + "add": { + "read_only": { "users": ["bob"] } + }, + "revoke": { + "read_only": { "users": ["alice"] } + } +} +``` +{% include copy-curl.html %} + +--- + +## 3. Get sharing info + +``` +GET _plugins/_security/api/resource/share?resource_id=&resource_type= +``` +{% include copy-curl.html %} + +--- + +## 4. List resource types + +``` +GET _plugins/_security/api/resource/types +``` +{% include copy-curl.html %} + +Returns action groups declared by plugins. + +--- + +## 5. List accessible resources + +``` +GET _plugins/_security/api/resource/list?resource_type= +``` +{% include copy-curl.html %} + +Returns only resources visible to the caller. + +--- + +## 6. Migration API (admin-only) + +Used once to import legacy plugin-managed sharing metadata. + +``` +POST _plugins/_security/api/resources/migrate +{ + "source_index": "", + "username_path": "", # e.g. /owner/name + "backend_roles_path": "", # e.g. /owner/backend_roles + "default_owner": "some_user", + "default_access_level": { + "": "" # if resource-index has more than one resource type add more entries + } +} + +``` +{% include copy-curl.html %} + + +--- + +# Restrictions + +* Only owners, super-admins and users with sharing access can share or revoke access. +* All resource indices must be system indices. +* System index protection must be enabled. +* Users still require plugin-level cluster permissions, specifically for creating resources. +* Action-groups must be declared in plugin configuration. + +--- + +# Best practices + +For developers: + +* Use SPI and ResourceSharingClient instead of custom ACL logic. +* Store only consistent resource types in a resource index. +* Use the implicit DLS filtering by running searches under system identity. + +For admins: + +* Enable the feature on fresh clusters first. +* Keep system index protection enabled. +* Share resources minimally and explicitly. + +--- + +# Conclusion + +The Resource Sharing and Access Control framework provides a unified and secure way to implement document-level access control for plugin-defined resources in OpenSearch. It introduces a standardized SPI, central sharing index, and new REST APIs for fine-grained authorization. + +For implementation examples, see the **sample-resource-plugin** in the security plugin repository. +For more detailed documentation on this feature, please see [RESOURCE_SHARING_AND_ACCESS_CONTROL.md](https://github.com/opensearch-project/security/blob/main/RESOURCE_SHARING_AND_ACCESS_CONTROL.md). + +--- +