You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2025-05-19-journey-to-find-replacements-java-security-manager.md
+17-17Lines changed: 17 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,14 +18,14 @@ The decision to remove JSM in 3.0 was carefully considered and primarily driven
18
18
19
19
1.**The upcoming removal of JSM from the Java platform**: JSM has been deprecated since JDK 17 ([JEP411](https://openjdk.org/jeps/411)) and is scheduled for full removal in JDK 24 ([JEP 486](https://openjdk.org/jeps/486)). According to the Java Enhancement Proposal (JEP), this decision was made because very few projects were using JSM, with Elasticsearch being one of the few major open-source projects that did. While OpenSearch 3.0 is bundled with Java 21 and not yet forced to drop JSM, continuing to rely on a deprecated and soon-to-be-removed component was deemed unsustainable for long-term support and innovation.
20
20
21
-
2.**Incompatibility with emerging JVM features, particularly, virtual threads**: Introduced in ([JEP 444](https://openjdk.org/jeps/444)), virtual threads are one of the most anticipated features in modern Java. While OpenSearch 3.0 does not use virtual threads internally, we expect plugin developers and future versions of OpenSearch to explore using virtual threads for improved scalability. However, virtual threads do not carry permissions when a Security Manager is enabled, effectively rendering them incompatible with any JSM-based security model. Thus, continuing to support JSM would have prevented adoption of a key Java feature that unlocks better concurrency and resource efficiency.
21
+
2.**Incompatibility with emerging JVM features, particularly virtual threads**: Introduced in ([JEP 444](https://openjdk.org/jeps/444)), virtual threads are one of the most anticipated features in modern Java. While OpenSearch 3.0 does not use virtual threads internally, we expect plugin developers and future versions of OpenSearch to potentially use virtual threads for improved scalability. However, virtual threads do not carry permissions when a Security Manager is enabled, effectively rendering them incompatible with any JSM-based security model. Thus, continuing to support JSM would have prevented adoption of a key Java feature that unlocks better concurrency and resource efficiency.
22
22
23
23
Given these needs, we decided to deprecate JSM in OpenSearch 3.0. Doing this in a major version allowed us to communicate the change clearly and avoid introducing breaking security changes in later 3.x minor releases.
24
24
25
25
26
-
In December 2021, an [issue](https://github.com/opensearch-project/OpenSearch/issues/1687) was created in the OpenSearch core repo to discuss options for a replacement. Soon it became clear that there was no direct replacement to the functionality that JSM provided for Java programs. OpenSearch embarked on a lengthy search for a replacement that sought to retain important functionality from JSM that OpenSearch relied on.
26
+
In December 2021, an [issue](https://github.com/opensearch-project/OpenSearch/issues/1687) was created in the OpenSearch core repo to discuss options for a replacement. It soon became clear that there was no direct replacement for the functionality that JSM provided for Java programs. OpenSearch embarked on a lengthy search for a replacement that would retain critical JSM functionality.
27
27
28
-
We considered many different options, including the following notable ones:
28
+
We considered many different options, including the following:
29
29
30
30
1. Moving to [OpenSearch extensibility](https://opensearch.org/blog/technical-roadmap-opensearch-extensibility/) through out-of-process extensions (a radical change).
31
31
2. Replacing JVM with GraalVM.
@@ -35,17 +35,17 @@ We considered many different options, including the following notable ones:
35
35
36
36
## Understanding JSM's role in OpenSearch
37
37
38
-
At its core, OpenSearch is a powerful search engine built on top of Apache Lucene. It provides a REST API layer for accessing documents stored in Lucene shards, along with built-in cluster management for running Lucene on nodes distributed across a cluster. OpenSearch has a pluggable architecture and a diverse set of plugins that extend the core functionality by offering additional features like security, observability, and index management. OpenSearch plugins run in the same JVM as the OpenSearch process but remain partially separated through separate class loading. OpenSearch does not treat plugins as secure-by-default; instead, it relies on JSM to sandbox plugins in order to prevent them from performing privileged actions without explicit approval by a cluster administrator.
38
+
At its core, OpenSearch is a powerful search engine built on top of Apache Lucene. It provides a REST API layer for accessing documents stored in Lucene shards, along with built-in cluster management for running Lucene on nodes distributed across a cluster. OpenSearch has a pluggable architecture and a diverse set of plugins that extend the core functionality by offering additional features like security, observability, and index management. OpenSearch plugins run in the same JVM as the OpenSearch process but remain partially separated through separate class loading. OpenSearch does not treat plugins as secure by default; instead, it relies on JSM to sandbox plugins in order to prevent them from performing privileged actions without explicit cluster administrator approval.
39
39
40
-
There are two main groups of users that interface with JSM: plugin developers and cluster administrators. These groups use JSM in different ways.
40
+
Two main user groups use JSM: plugin developers and cluster administrators. These groups use JSM in different ways.
41
41
42
42
### How plugin developers use JSM
43
43
44
44
To perform a privileged action, plugin developers must wrap the code that performs the action in an `AccessController.doPrivileged(() -> { ... })` block and grant the necessary permissions in the `plugin-security.policy` file. A common complaint about JSM is that plugin developers don't know what constitutes a `PrivilegedAction` until runtime. At runtime, they get an error saying that the plugin is forbidden from performing a given operation, for example, connecting to a socket or reading from the file system. JSM enforced a broad range of restrictions, from preventing calls to system operations like `System.exit` to other Java language features like reflection (for more information about the areas that JSM covered, see [Permissions and Security Policy](https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc3.html)).
45
45
46
-
Plugin developers interface with JSM by defining permissions in a policy file and implementing privileged actions in code:
46
+
Plugin developers use JSM by defining permissions in a policy file and implementing privileged actions in code:
47
47
48
-
- The following example `plugin-security.policy` file defines the basic permissions a plugin needs to operate:
48
+
- The following example `plugin-security.policy` file defines the basic permissions needed for a plugin to operate:
49
49
50
50
```json
51
51
grant {
@@ -89,16 +89,16 @@ Cluster administrators are prompted about permissions that a plugin requests at
89
89
90
90
## Our solution for replacing JSM
91
91
92
-
Understanding the key user interactions with JSM was crucial as we developed our replacement strategy. We needed solutions that would continue to support both plugin developers' need for privileged operations and administrators' ability to control permissions.
92
+
Understanding the key JSM user interactions was crucial as we developed our replacement strategy. We needed solutions that would continue to support both plugin developers' need for privileged operations and administrators' ability to control permissions.
93
93
94
-
After evaluating potential JSM replacement alternatives, it was clear that no single approach could replace all of the functionality that JSM provided. The OpenSearch community came to a consensus to replace JSM by adopting a two-pronged strategy:
94
+
After evaluating potential JSM replacement alternatives, it was clear that no single approach could replace all of the functionality that JSM provided. The OpenSearch community decided to replace JSM by adopting a two-pronged strategy:
95
95
96
-
1. [`systemd` hardening](#systemd-hardening) - Using operating system controls for protection.
97
-
2. [Java agent](#java-agent) - Implementing a low-level instrumentation to intercept and authorize privileged operations.
96
+
1. [`systemd` hardening](#systemd-hardening): Using operating system controls for protection.
97
+
2. [Java agent](#java-agent): Implementing low-level instrumentation to intercept and authorize privileged operations.
98
98
99
99
### systemd hardening
100
100
101
-
The first component of the replacement strategy is `systemd` hardening, which is available on Linux distributions that use `systemd` as the init system. This approach sandboxes the OpenSearch process using the following native operating system features:
101
+
The first component of the replacement strategy was `systemd` hardening, which is available in Linux distributions that use `systemd` as the init system. This approach sandboxes the OpenSearch process using the following native operating system features:
102
102
103
103
- **System call restriction**: Uses `seccomp` and the `SystemCallFilter` directive to restrict the kernel interfaces that the OpenSearch process can access.
104
104
@@ -108,17 +108,17 @@ The first component of the replacement strategy is `systemd` hardening, which is
108
108
109
109
- **Process containment**: Enables options such as `PrivateTmp`, `NoNewPrivileges`, and `ProtectSystem` to further reduce the risk of privilege escalation or file system tampering.
110
110
111
-
This approach is effective for protecting the system from malicious plugins by constraining the actions that the OpenSearch process can perform. However, the drawback is that `systemd` rules are applied at the process level, not at the plugin level. This means that any privilege granted affects the entire OpenSearch process, which is not a suitable replacement for the fine-grained, per-plugin control that JSM provided.
111
+
This approach effectively protects the system from malicious plugins by constraining the actions that the OpenSearch process can perform. However, the drawback is that `systemd` rules are applied at the process level, not at the plugin level. This means that any privilege granted affects the entire OpenSearch process, resulting in an unsuitable replacement for the fine-grained, per-plugin control that JSM provided.
112
112
113
113
### Java agent
114
114
115
-
The second component of the replacement strategy is a custom Java agent. A Java agent is a special JAR that the JVM can load before application execution or attach during execution in order to view, transform, or monitor the bytecode of every class that the JVM loads. Internally, it relies on the Instrumentation API introduced in Java 5. A Java agent is attached to the OpenSearch process through the `-javaagent` Java argument. The OpenSearch Java agent is composed of interceptors that monitor privileged operations and ensure that the executing codebase has been explicitly granted the required permissions. The configuration for the Java agent remains consistent with the Java Security Manager: the `plugin-security.policy` file defines the set of granted permissions and prompts the cluster administrator during plugin installation.
115
+
The second component of the replacement strategy was a custom Java agent. A Java agent is a special JAR that the JVM can load before application execution or attach during execution in order to view, transform, or monitor the bytecode of every class that the JVM loads. Internally, it relies on the Instrumentation API introduced in Java 5. A Java agent is attached to the OpenSearch process through the `-javaagent` Java argument. The OpenSearch Java agent is composed of interceptors that monitor privileged operations and ensure that the executing codebase has been explicitly granted the required permissions. The configuration for the Java agent remains consistent with JSM: the `plugin-security.policy` file defines the set of granted permissions and prompts the cluster administrator during plugin installation.
116
116
117
-
OpenSearch's Java Agent uses the ByteBuddy Instrumentation API to intercept and instrument Java bytecode at runtime. Specifically, the agent installs interceptors for privileged operations such as:
117
+
OpenSearch's Java agent uses the ByteBuddy Instrumentation API to intercept and instrument Java bytecode at runtime. Specifically, the agent installs interceptors for privileged operations such as:
118
118
119
-
- Opening or connecting sockets
119
+
- Opening or connecting sockets.
120
120
121
-
- Creating, reading, or writing files
121
+
- Creating, reading, or writing files.
122
122
123
123
These interceptors inspect the current call stack to identify the originating code and then evaluate whether it has been granted the required permissions based on the existing `plugin-security.policy` file. This mirrors the existing JSM model, with minimal disruption for plugin developers and administrators.
0 commit comments