Safeguard
Vulnerabilities

The Java Security Manager Is Deprecated: What to Use Instead

JEP 411 deprecated the Java Security Manager for removal, and years of accumulated java security flaws in its trust model are why the platform is retiring it rather than fixing it further.

Safeguard Team
Product
5 min read

The Java Security Manager — the mechanism Java has used since its earliest versions to sandbox code and restrict what a running program is allowed to do — was formally deprecated for removal under JEP 411, starting with JDK 17. That's a significant change for any team that built a security architecture around it, and it's worth understanding both why the platform moved away from it and what actually replaces the functionality in a modern Java stack.

What was the Java Security Manager supposed to do?

It let a JVM run code under a fine-grained permission model — restricting file system access, network calls, reflection, and dozens of other capabilities — originally designed for a world where Java applets and untrusted code routinely ran inside a browser or shared host. That threat model made sense in the mid-1990s and early 2000s; it makes much less sense today, when applets are gone, most Java workloads run as trusted server-side services inside a container or VM boundary, and the isolation people actually need is handled by the operating system, the container runtime, or the cloud platform rather than the language runtime itself.

Why deprecate it instead of continuing to patch it?

Because the Security Manager's per-permission model had become expensive to maintain and rarely used correctly. The OpenJDK team's own rationale, published alongside JEP 411, noted that the mechanism was rarely enabled in real deployments — configuring it correctly required a granular, error-prone permissions file that most teams either got wrong (over-permissive, defeating the purpose) or never enabled in the first place because it broke normal application behavior. A security control that's technically present but practically unused doesn't reduce risk; it just adds maintenance burden to the platform while providing a false sense of coverage. Retiring it also freed the JDK team to optimize other parts of the runtime without preserving compatibility with a feature almost nobody used as designed.

What actually replaces the Security Manager today?

Isolation has moved to layers outside the JVM: container boundaries (Docker, Kubernetes pod security contexts), OS-level sandboxing (seccomp profiles, gVisor, Firecracker microVMs), and cloud-provider isolation (separate compute instances, IAM-scoped service accounts) now do the job the Security Manager was originally meant to do, generally more reliably because they don't depend on every line of application code cooperating with a permission check. Inside the application itself, the Java Platform Module System (JPMS, introduced in Java 9) provides a different but complementary kind of boundary — restricting which packages are exposed across module boundaries — though it addresses encapsulation, not runtime permission enforcement, so it isn't a drop-in replacement for every Security Manager use case.

Does removing the Security Manager introduce new java security flaws?

Not directly — removal doesn't add a vulnerability, but it does mean any application that genuinely depended on Security Manager-enforced sandboxing (rather than just having it nominally configured) needs a migration plan before upgrading to a JDK version where it's fully removed rather than merely deprecated. The more common risk is teams discovering, mid-upgrade, that a library or framework they depend on still checks for Security Manager presence in ways that break unexpectedly. Auditing dependencies for Security Manager usage before a major JDK upgrade — and testing the actual isolation boundary an application needs against its replacement (container policy, seccomp profile, or IAM scoping) — is the practical migration step most teams skip until the upgrade is already underway.

What should teams do if they relied on it for plugin or extension sandboxing?

This is the hardest migration case, because a surprising number of frameworks — build tools, application servers, and plugin-based systems — used the Security Manager specifically to sandbox untrusted or semi-trusted plugin code running inside the same JVM as the host application, rather than for the classic applet use case. Maven, for instance, and various application servers historically offered Security-Manager-based plugin isolation as an option. Without it, the practical alternatives are running untrusted plugin code in a genuinely separate process (with its own OS-level sandboxing) rather than in-process, or redesigning the plugin interface so untrusted code simply can't reach sensitive APIs in the first place, rather than reaching them and being blocked by a runtime permission check. Neither option is a drop-in replacement, which is why teams with this specific dependency on the Security Manager have generally had the longest migration timelines.

How Safeguard fits into this migration

Safeguard's SCA and SAST/DAST scanning flag both outdated JDK versions carrying deprecated APIs and code paths that still reference SecurityManager directly, so a Java upgrade project surfaces those call sites automatically instead of relying on a manual grep across a large codebase before a JDK version bump.

FAQ

Is the Java Security Manager already removed, or just deprecated?

It was deprecated for removal starting with JDK 17 under JEP 411 and disabled by default in subsequent releases, with the platform's stated direction being full removal — teams should treat "deprecated" as a firm signal to migrate rather than wait.

Does this affect Android, which also uses Java?

No — Android has its own separate security and permission model (the Android application sandbox, enforced at the OS and package-manager level) that doesn't rely on the same java.lang.SecurityManager mechanism used by standard JVMs.

What should a team do first if they still rely on Security Manager?

Inventory every call site that references SecurityManager, AccessController, or related APIs, then map each one to the isolation boundary it's actually trying to enforce — container policy, seccomp, or IAM scoping — before attempting the JDK upgrade rather than during it.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.