-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
Is your feature request related to a problem? Please describe
This is a proposal to gather community feedback on the permanent deprecation of the Security Manager (JSM) starting in OpenSearch 3.0
The Security Manager will reach its end-of-life in JDK 24 (see https://openjdk.org/jeps/486 #1687). OpenSearch 3.0, which will be bundled with JDK 21, could potentially still support the Security Manager. However, we propose to disable it starting in version 3.0 (see [1] for reasoning). By "disabling," we mean that OpenSearch will not initialize the Security Manager during the bootstrap process. If we decide to turn it off in 3.0, there will be no option to revert this decision—meaning the Security Manager will be permanently disabled in OpenSearch.
[1] JDK 21 introduces virtual threads, based on: JEP 444: Virtual Threads, "Virtual threads have no permissions when running with a SecurityManager set." This means that any code using virtual threads under a Security Manager will not work. While OpenSearch 3.0 itself will not contain virtual threads, we anticipate that developers—especially plugin developers—will want to leverage them in future 3.x versions. To support this, we could consider disabling the Security Manager in a later 3.x release. There is a strong argument for not deprecating a security feature unless absolutely necessary. However, deprecating such a significant security feature in a minor version release is generally not acceptable. An alternative approach could be to introduce a new major version (4.0) with the Security Manager disabled. However, it is too early to predict the lifecycle of major versions, as they tend to last a long time (for example, the 2.x series lasted around two years).
Over last few months we have been working on finding alternatives (also discussed later) for security manager. The alternatives are not a drop-in-replacement of security manager. Our research into alternatives has been extensive, and we believe the same solutions could be applicable across OpenSearch 3.0, 3.x, and 4.x. Hence we propose disabling in the major version release of 3.0
The most critical question remains: "Are these alternatives sufficient?" That is the feedback we seek from the community. If there are no major blockers, we will proceed with disabling the Security Manager in 3.0. Otherwise, we will delay the decision until absolutely necessary or until we find a better replacement.
Describe the solution you'd like
We propose below two alternatives as replacement for security manager.
-
[Security Manager Replacement] Strengthen OS core security via systemd configuration #16729:
Systemd offers a whole lot of security configs to isolate linux processes as well as isolate a bad actor effecting the underlying operating system. The core idea is to protect the Opensearch process from being effected (e.g system exit) from untrusted code (certain plugins). It can allow or blocks specific system calls using seccomp filters heavily reducing the attack surface of the exposed kernel. It can be used to allow or deny access to socket and files. -
Java Agent [POC] [Security Manager Replacement] Native Java Agent (dynamic code rewriting, must be low overhead) #16731: With security manager we can define permissions at plugin level, elevating socket, file access or thread context permissions at an individual plugin level. This is not possible with
systemdbecause it rules are defined at process level. Elevating permissions at process level is unacceptable. To mimic security manager: we introduced a "Java agent" which is a special type of class (in Java) that can modify the bytecode at runtime. They use Java Instrumentation API to intercept and modify the behavior of applications running on the JVM. We can launch a java agent which can intercept calls like SocketChannel.connect() or File.createNewFile() enforcing a security-policy which decides if a FileIO or Socket connect is allowed or not. Interestingly we can apply the same security policies that are being used today for plugins (a less of a breaking change). However, writing an interceptor requires a whole lot of boiler-plate code and hard for maintainability so we take the trade-off to implement interceptors only for Socket and File access (the most dangerous ones).
"While these are the two alternatives we are initially proposing and could be available in 3.0, we remain open to other solutions that can be incorporated as we continue enhancing security in layers."
No going back:
Once we have turned-off security manager we actually allow developers to run their code with no more wrapping around AccessController.doPrivileged() block. An attempt to turn-back-on the security manager means breaking these code paths, hence no going back.
Late clean-up of AccessController.doPrivileged():
Executing code within AccessController.doPrivileged() with the Security Manager disabled neither enforces any policy evaluation nor has any side effects—it effectively becomes dead code. This dead code will not be removed in 3.0 but may be cleaned up in later versions as a non-breaking change.
Comparison of Java Security Manager vs. systemd Security Configurations
(the comparison excludes File and Socket permissions, because they would be covered just like today via the java agent)
| Protection domain | SM | systemd | Covered by alternative? |
|---|---|---|---|
| Management Permissions | java.lang.management.ManagementPermission "control" |
Not explicitly covered | No |
java.lang.management.ManagementPermission "monitor" |
Not explicitly covered | No | |
| Reflection & Runtime Permissions | java.lang.reflect.ReflectPermission "suppressAccessChecks" |
NoNewPrivileges=true (Prevents privilege escalation) |
Partially |
java.lang.RuntimePermission "accessClassInPackage.*" |
MemoryDenyWriteExecute=true (Prevents modification) |
Partially | |
java.lang.RuntimePermission "createClassLoader" |
NoNewPrivileges=true (Prevents spawning new privileged processes) |
Yes | |
java.lang.RuntimePermission "setContextClassLoader" |
Not explicitly covered | No | |
java.lang.RuntimePermission "modifyThread" |
RestrictNamespaces=true (Prevents manipulation) |
Yes | |
java.lang.RuntimePermission "modifyThreadGroup" |
RestrictNamespaces=true (Prevents manipulation) |
Yes | |
java.lang.RuntimePermission "shutdownHooks" |
CapabilityBoundingSet=~CAP_SYS_ADMIN (Restricts shutdown abilities) |
Yes | |
| Network Permissions | java.net.NetPermission "getProxySelector" |
RestrictAddressFamilies=~AF_INET ~AF_INET6 (Blocks internet) |
Yes |
java.net.NetPermission "setDefaultAuthenticator" |
Not explicitly covered | No | |
| Security & Cryptographic Permissions | java.security.SecurityPermission "createAccessControlContext" |
ProtectSystem=full (Limits modifications to system-wide security settings) |
Yes |
java.security.SecurityPermission "insertProvider.SaslPlainServer" |
ProtectSystem=strict (Prevents unprivileged modifications) |
Yes | |
| Logging Permissions | java.util.logging.LoggingPermission "control" |
Not explicitly covered | No |
| Property Permissions | java.util.PropertyPermission "os.name", "read" |
ProtectSystem=full (Restricts system property tampering) |
Yes |
java.util.PropertyPermission "opensearch.path.conf", "read,write" |
ReadWritePaths=/var/lib/opensearch (Controls file-level permissions) |
Yes | |
java.util.PropertyPermission "opensearch.allow_insecure_settings", "read,write" |
Some settings may be restricted under ProtectSystem=strict |
||
| JMX & MBean Permissions | javax.management.MBeanServerPermission "createMBeanServer" |
Not explicitly covered | No |
javax.management.MBeanTrustPermission "register" |
Not explicitly covered | No | |
| Authentication & Security Contexts | javax.security.auth.AuthPermission "doAs" |
NoNewPrivileges=true (Restricts privilege escalation) |
Yes |
javax.security.auth.AuthPermission "modifyPrincipals" |
Not explicitly covered | No | |
javax.security.auth.AuthPermission "modifyPrivateCredentials" |
Not explicitly covered | No | |
| Process & Execution Restrictions | Not explicitly in Java | MemoryDenyWriteExecute=true (Prevents execution in writable memory) |
Yes |
| N/A | RestrictRealtime=true (Blocks real-time scheduling) |
Yes | |
| N/A | LockPersonality=true (Prevents ABI changes) |
Yes | |
| N/A | ProtectClock=true (Prevents time manipulation) |
Yes | |
| Kernel & System Protection | Not explicitly in Java | ProtectKernelModules=true (Prevents module loading) |
Yes |
| N/A | ProtectKernelLogs=true (Prevents reading logs) |
Yes | |
| N/A | ProtectControlGroups=true (Prevents cgroup modifications) |
Yes | |
| Namespace & SUID Restrictions | N/A | RestrictNamespaces=true (Prevents unprivileged namespace changes) |
Yes |
| N/A | RestrictSUIDSGID=true (Prevents privilege escalation via SUID binaries) |
Yes |
So, let us know your thoughts!
Metadata
Metadata
Assignees
Labels
Type
Projects
Status