Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ Cumulative feature documentation across all versions.
- Painless Script Hashing Methods
- Snapshot Repository
- Synonym Analyzer Configuration

## security

- Security Identity Plugin
115 changes: 115 additions & 0 deletions docs/features/security/security-identity-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
tags:
- security
---
# Security Identity Plugin

## Summary

The Security Identity Plugin feature provides plugin-aware identity management in OpenSearch, enabling plugins to securely access their own system indices while preventing unauthorized cross-plugin access. This strengthens the security model by replacing the previous "trusted mode" approach where stashing the ThreadContext granted unrestricted access.

## Details

### Architecture

```mermaid
graph TB
subgraph "Plugin Request Flow"
A[Plugin API Handler] --> B{pluginSubject.runAs}
B --> C[ContextProvidingPluginSubject]
C --> D[ThreadContext with Plugin Identity]
D --> E[SecurityFilter]
end

subgraph "Privilege Evaluation"
E --> F{Is Plugin User?}
F -->|Yes| G[SystemIndexAccessEvaluator]
F -->|No| H[Standard User Evaluation]
G --> I{Owns System Index?}
I -->|Yes| J[Allow]
I -->|No| K[Deny]
end
```

### Components

| Component | Description |
|-----------|-------------|
| `IdentityPlugin` | Core interface implemented by security plugin for identity management |
| `PluginSubject` | Interface representing a plugin's identity for privileged operations |
| `ContextProvidingPluginSubject` | Security plugin implementation that injects plugin identity into ThreadContext |
| `UserSubject` | Interface representing an authenticated user's identity |
| `UserSubjectImpl` | Security plugin implementation for user subjects |
| `SystemIndexAccessEvaluator` | Evaluates plugin access to system indices based on ownership |

### Configuration

The feature is controlled by the following setting:

| Setting | Description | Default |
|---------|-------------|---------|
| `plugins.security.system_indices.enabled` | Enable system index protection | `true` |

When enabled, plugins can only access system indices they registered via `SystemIndexPlugin.getSystemIndexDescriptors()`.

### Usage Example

Plugins implementing `IdentityAwarePlugin` receive a `PluginSubject` during initialization:

```java
public class MyPlugin extends Plugin implements SystemIndexPlugin, IdentityAwarePlugin {
private PluginSubject pluginSubject;

@Override
public void assignSubject(PluginSubject pluginSubject) {
this.pluginSubject = pluginSubject;
}

// Use pluginSubject.runAs() for system index operations
public void indexDocument() {
pluginSubject.runAs(() -> {
client.index(new IndexRequest(MY_SYSTEM_INDEX)
.source("{\"data\":\"value\"}", XContentType.JSON));
return null;
});
}
}
```

### Plugin Identity Convention

Plugin users follow the naming convention:
- Format: `plugin:{canonical-class-name}`
- Example: `plugin:org.opensearch.alerting.AlertingPlugin`

The `:` character is forbidden in regular usernames, preventing identity spoofing.

## Limitations

- Plugins cannot perform cluster-level actions using `pluginSubject.runAs()`
- Cross-plugin system index access is blocked
- Bulk operations spanning multiple plugins' system indices are rejected
- Backward compatibility: Plugin users are not serialized to nodes running versions prior to v2.19.0

## Change History

- **v2.19.0** (2025-02): Initial implementation of IdentityPlugin extension points and ContextProvidingPluginSubject

## References

### Documentation

- [Authorization tokens](https://docs.opensearch.org/2.19/security/access-control/authentication-tokens/) - IdentityPlugin interface documentation

### Pull Requests

| Version | PR | Description |
|---------|-----|-------------|
| v2.19.0 | [#5028](https://github.com/opensearch-project/security/pull/5028) | Backport IdentityPlugin implementation to 2.x |
| v2.19.0 | [#5037](https://github.com/opensearch-project/security/pull/5037) | Legacy authz code path support |
| v2.19.0 | [#5032](https://github.com/opensearch-project/security/pull/5032) | Fix search operations with pluginSubject.runAs |
| v2.19.0 | [#5055](https://github.com/opensearch-project/security/pull/5055) | Fix update operations with pluginSubject.runAs |

### Related Issues

- [#4439](https://github.com/opensearch-project/security/issues/4439): RFC - Strengthen System Index Protection in the Plugin Ecosystem
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
tags:
- security
---
# Security Identity Plugin

## Summary

OpenSearch v2.19.0 introduces new extension points in the `IdentityPlugin` interface and adds `ContextProvidingPluginSubject` to strengthen system index protection in the plugin ecosystem. This enhancement allows plugins to securely access their own system indices using `pluginSubject.runAs()` while preventing unauthorized access to other plugins' system indices.

## Details

### What's New in v2.19.0

The security plugin now implements the `IdentityPlugin` interface from OpenSearch core, providing:

1. **ContextProvidingPluginSubject**: A new class that populates a header in the ThreadContext with the canonical class name of the plugin executing code using `pluginSubject.runAs()`.

2. **Plugin-Aware System Index Access**: Plugins can now perform index operations on their own registered system indices without requiring full admin privileges.

3. **Enhanced Privilege Evaluation**: The security plugin evaluates whether a plugin is authorized to access specific system indices based on the plugin's identity.

### Technical Changes

#### New Classes

| Class | Description |
|-------|-------------|
| `ContextProvidingPluginSubject` | Implements `PluginSubject` interface, manages plugin identity in ThreadContext |
| `UserSubjectImpl` | Implements `UserSubject` interface for authenticated users |
| `InMemorySecurityRoles` | Interface for dynamically created security roles |
| `InMemorySecurityRolesV7` | Implementation for plugin-specific security roles |

#### Key Implementation Details

- Plugins are identified by the convention `plugin:{canonical-class-name}` (e.g., `plugin:org.opensearch.security.systemindex.sampleplugin.SystemIndexPlugin1`)
- The `:` character is forbidden in regular usernames, ensuring plugin identities cannot be spoofed
- Plugin users can only perform index operations on system indices they registered via `SystemIndexPlugin.getSystemIndexDescriptors()`
- Cluster actions (like `cluster:monitor/health`) are not permitted for plugin subjects by default

#### Security Filter Changes

The `SecurityFilter` now:
- Skips automatic privilege bypass when a plugin user is detected
- Evaluates system index access based on plugin ownership
- Allows plugins to perform bulk operations on their own system indices

```java
// Example: Plugin accessing its own system index
pluginSubject.runAs(() -> {
client.index(new IndexRequest(SYSTEM_INDEX_1)
.source("{\"content\":1}", XContentType.JSON));
return null;
});
```

### Migration from ThreadContext Stashing

Previously, plugins used `threadContext.stashContext()` to perform privileged operations:

```java
// Old approach (deprecated)
try (ThreadContext.StoredContext ctx = threadContext.stashContext()) {
// Operations on system index
}
```

The new approach uses `pluginSubject.runAs()`:

```java
// New approach (v2.19.0+)
pluginSubject.runAs(() -> {
// Operations on system index
return null;
});
```

## Limitations

- Plugins cannot perform cluster-level actions (e.g., `cluster:monitor/health`) using `pluginSubject.runAs()`
- Plugins can only access system indices they explicitly registered
- Bulk operations targeting multiple system indices from different plugins will be rejected
- The feature requires `plugins.security.system_indices.enabled` to be `true` (default)

## References

### Pull Requests

| PR | Description | Related Issue |
|----|-------------|---------------|
| [#5028](https://github.com/opensearch-project/security/pull/5028) | Backport #4896 to 2.x - Implement new extension points in IdentityPlugin | - |
| [#5037](https://github.com/opensearch-project/security/pull/5037) | Implement IdentityPlugin extension points for legacy authz code path | [#4439](https://github.com/opensearch-project/security/issues/4439) |
| [#5032](https://github.com/opensearch-project/security/pull/5032) | Fix plugin search operations on system index with pluginSubject.runAs | - |
| [#5055](https://github.com/opensearch-project/security/pull/5055) | Fix plugin update operations on system index with pluginSubject.runAs | - |

### Related Issues

- [#4439](https://github.com/opensearch-project/security/issues/4439): RFC - Strengthen System Index Protection in the Plugin Ecosystem
1 change: 1 addition & 0 deletions docs/releases/v2.19.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
- CVE Fixes
- JWT Authentication Bug Fixes
- Security Audit Logging
- Security Identity Plugin
- Security Netty
- Security Roles

Expand Down