Re: Authorization layer API and low level access checks.
Updated authorization layer prototype: https://github.com/pfirmstone/HighPerformanceSecurity On 30/06/2021 9:38 pm, Peter Firmstone wrote: A draft Authorization implementation, untested. -- Regards, Peter Firmstone
Re: Authorization layer API and low level access checks.
A draft Authorization implementation, untested. -- Regards, Peter Firmstone /** * Authorization class, instances contain the domains and Subject of the * Authorization context, used for Authorization decisions by Guard * implementations. Provides static utility methods to make privilgedCall's * and record the current context. * * @author peter */ public final class Authorization { private static final ProtectionDomain MY_DOMAIN = Authorization.class.getProtectionDomain(); private static final Authorization PRIVILEGED = new Authorization(new ProtectionDomain []{ MY_DOMAIN }); private static final Authorization UNPRIVILEGED = new Authorization( new ProtectionDomain[]{ new ProtectionDomain( new CodeSource(null, (Certificate [])null), null ) } ); private static final ThreadLocal INHERITED_CONTEXT = new ThreadLocal(); private static final Guard GUARD_REGISTER_CHECK = GuardBuilder.getInstance("RUNTIME").get("registerGuard", (String) null); private static final Guard GUARD_SUBJECT = GuardBuilder.getInstance("AUTH").get("getSubjectFromAuthorization", null); private static final Set> GUARDS = RC.set(Collections.newSetFromMap(new ConcurrentHashMap<>()), Ref.WEAK, 0); /** * Elevates the privileges of the Callable to those granted to the Subject * and ProtectionDomain's of the Callable and it's call stack, including the * ProtectionDomain of the caller of this method. * * @param * @param c * @return */ public static Callable privilegedCall(Callable c){ Authorization auth = INHERITED_CONTEXT.get(); try { INHERITED_CONTEXT.set(PRIVILEGED); if (auth != null){ return privilegedCall(auth.getSubject(), c); } else { return new CallableWrapper<>(new Authorization(captureCallerDomain(null), null), c); } } finally { INHERITED_CONTEXT.set(auth); } } /** * Elevates the privileges of the Callable to those granted to the Subject * and ProtectionDomain's of the Callable and it's call stack, including the * ProtectionDomain of the caller of this method. * * @param * @param subject * @param c * @return */ public static Callable privilegedCall(Subject subject, Callable c){ Authorization authorization = INHERITED_CONTEXT.get(); try { INHERITED_CONTEXT.set(PRIVILEGED); Set p = subject != null ? subject.getPrincipals() : null; Principal [] principals = p != null ? p.toArray(new Principal[p.size()]) : null; return new CallableWrapper<>(new Authorization(captureCallerDomain(principals), subject), c); } finally { INHERITED_CONTEXT.set(authorization); } } /** * Elevates the privileges of the Callable to those granted to the Subject * and ProtectionDomain's of the Callable and it's call stack, including the * ProtectionDomain of the caller of this method and the Authorization * context provided. * * @param * @param ac * @param c * @return */ public static Callable privilegedCall(Authorization ac, Callable c){ if (c == null) throw new IllegalArgumentException("Callable cannot be null"); if (ac != null){ Authorization authorization = INHERITED_CONTEXT.get(); try { INHERITED_CONTEXT.set(PRIVILEGED); Subject subject = ac.getSubject(); Set p = subject != null ? subject.getPrincipals() : null; Principal [] principals = p != null ? p.toArray(new Principal[p.size()]) : null; Set domains = captureCallerDomain(principals); ac.checkEach((ProtectionDomain t) -> { if (MY_DOMAIN.equals(t)) return; if (principals != null){ domains.add( new ProtectionDomainKey(t, principals) ); } else { domains.add(new ProtectionDomainKey(t)); } }); Authorization auth = new Authorization(domains, subject); return new CallableWrapper<>(auth, c); } finally { INHERITED_CONTEXT.set(authorization); } } else { return privilegedCall(c); } } private static Set captureCallerDomain(Principal [] principals){ Set options = new HashSet<>(); options.add(Option.RETAIN_CLASS_REFERENCE); StackWalker walker = StackWalker.getInstance(options); List frames = walker.walk(s -> s.dropWhile(f ->
Re: READ 1ST: Re: Authorization layer API and low level access checks
Since I need to implement an authorization layer, and move past the current uncertainty surrounding authorization and authentication in Java, I think I'll start small and completely independent and learn from history. Requirements: 1. Ability to perform authorization checks on code and Subjects. 2. Compatible with all current Java LTS releases. 3. Will need to use Java API's, nothing platform specific. Uncertainty: 1. New JAAS API's are unknown, will they be suitable for our application? Unclear. 2. Will hooks be provided in OpenJDK for Guard checks or not? Unclear. 3. Lack of support for new features with existing API's going forward, eg virtual threads. 4. How to authenticate TLS and Kerberos connections without using deprecated API's? 5. Avoid other API's that may be removed in future due to under-utilisation. What can we do with what we know, how can we do it better? 1. Create a new Authorization.class with methods that return Callable objects that can be submitted to Executors, including virtual threads (assuming virtual threads support StackWalker). 2. Methods: * Callable privilegedCall(Callable c) // Always preserves subject, if any. * Callable privilegedCall(Subject s, Callable c) // Uses provided Subject, from LoginModule, or executing in the context of an authenticated client over a secure connection. * Callable privilegedCall(AuthorizationContext ac, Callable c) // Uses provided AuthorizationContext combined with context of the privileged caller. * AuthorizationContext getContext(); // Returns an optimized context (combines the inherited and calculated contexts, injects Principal[]'s from the Subject into each domain. Stored for later use when making privilegedCall's eg for TLS connection. 3. The Authorization.class implementation will enure that the inherited context is stored in a ThreadLocal variable which is restored to it's original value using a try finally block to ensure the inherited context is only present during the wrapped Callable's call. It's possible that privilegedCall's are nested in one thread, in which case the ThreadLocal value will be changed after each privilegedCall to the outer calls context, until it is set to null, by the outermost privilegedCall. 4. Callable returned can be submitted to an Executor, eg as a privileged task. 5. Create a new AuthorizationContext class * Encapsulates the current Subject * Contains a snapshot of the ProtectionDomains when the Callable was passed to privilegedCall and includes the domain of the class that called the Authorization.privileged method as well as any domains of Callable implementation parameter classes, this is the inherited context. * Methods: o Subject getSubject() // For secure connections. o void checkEach(Consumer consumer) throws AuthorizationException // Consumer::andThen allows for debugging information to be printed to error, such as print the privileges of a domain, or to record the required privileges of each domain, without throwing a SecurityException (when recording allowed operations). AuthorizationContext implementation determines how to execute. No mutable shared state. 4. Use Agents to instrument Java Public API until hooks are provided by OpenJDK. * *ONLY* target LTS releases to minimize API analysis required. * Use static analysis to located methods in Java API's that return sensitive classes, eg ClassLoader, ProtectionDomain. * We could use some hooks here OpenJDK? 5. How to capture domains and privileged scope? * It is not possible to inherit a call stack from a previous thread, so either the thread executes only platform code and is checked, assuming the platform code can be trusted to not allow sensitive object references to escape, or if application code is present, then it is unprivileged unless a privilegedCall is made. It will be known by the presence of a ThreadLocal inherited context whether a privilegedCall is being executed. * The stack context is only captured after a privilegedCall is made on a Thread's call stack, with the exception of a call stack that contains *only* platform code. * If an inherited ThreadLocal AuthorizationContext isn't present, when checked, then an unprivileged domain will represent the entire stack, with the following exception: o Unless all code on the thread stack is platform code, in this case, capture all domains on the call stack since the thread started. This is a code only check, as no Subject will be present. o For bootloader system code construct ProtectionDomain, with CodeSource URL[] containing a jrt:/$MODULE , if
Re: READ 1ST: Re: Authorization layer API and low level access checks
On 26/06/2021 3:41 pm, Peter Firmstone wrote: Apologies for multiple earlier emails, please ignore and read this instead. This proposal is about stripping out and simplifying as much of the dilapidated and complex SecurityManager infrastructure as possible, while retaining the ability for developers to implement a better high scaling and performant Authorization layer, without prohibitively preventing it. Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code to no longer call Permission implementations directly, instances obtained using GuardFactory, when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController's default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods for removal (make private), retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner. Create a new method AccessController::doUnprivileged, clear intent, to erase the DomainCombiner, and use the *unprivileged* AccessControlContext. Update AccessController.AccHolder.innocuousAcc to refer to an *unprivileged* context, as per the definition below. 8. Deprecate for removal the CodeSource::implies method. 9. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. 10. Deprecate for removal AccessController::checkPermission and AccessControlContext::checkPermission methods. AccessController.checkPermission calls AccessControlContext.optimize, which invokes the DomainCombiner, prior to calling AccessControlContext.checkPermission In my implementation of SecurityManager, I call AccessController.getContext from within a PrivilegedAction, to optimise a newly created AccessControlContext, (AccessController.getContext also calls AcessControlConext.optimize), prior to calling AccessControlContext.checkPermission. I think it would be simpler however, to create a new method in AccessController to replace checkPermission which also calls optimize. I think something could be done here with Stream and Consumer to perform the function checking ProtectionDomain's. Needs a little more thought, but basically we want to be able to check each ProtectionDomain, without being restricted to Permission or Policy implementations. Eg: AccessController.stream(AccessControlContext context).forEach(domain -> Check::domain) Or AccessController.checkDomains(AccessControlContext context, Consumer) This method would have a relevant Guard.check "RUNTIME" "getProtectionDomain" prior to calling AccessControlContext.optimize and the developer would need to make the call from a PrivilegedAction, and remember pass the relevant guard check for it's own AccessControlContext. 11. Undeprecate AccessController, AccessControlContext, DomainCombiner, SubjectDomainCombiner and Subject::doAs methods, while deprecating for removal methods stated in items above. 12. Deprecate for removal ProtectionDomain::implies, ProtectionDomain::getPermissions and ProtectionDomain::staticPermissionsOnly 13. Replace PermissionCollection type argument with Object in ProtectionDomain constructors,
READ 1ST: Re: Authorization layer API and low level access checks
Apologies for multiple earlier emails, please ignore and read this instead. This proposal is about stripping out and simplifying as much of the dilapidated and complex SecurityManager infrastructure as possible, while retaining the ability for developers to implement a better high scaling and performant Authorization layer, without prohibitively preventing it. Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code to no longer call Permission implementations directly, instances obtained using GuardFactory, when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController's default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods for removal (make private), retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner. Create a new method AccessController::doUnprivileged, clear intent, to erase the DomainCombiner, and use the *unprivileged* AccessControlContext. Update AccessController.AccHolder.innocuousAcc to refer to an *unprivileged* context, as per the definition below. 8. Deprecate for removal the CodeSource::implies method. 9. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. 10. Deprecate for removal AccessController::checkPermission and AccessControlContext::checkPermission methods. 11. Undeprecate AccessController, AccessControlContext, DomainCombiner, SubjectDomainCombiner and Subject::doAs methods, while deprecating for removal methods stated in items above. 12. Deprecate for removal ProtectionDomain::implies, ProtectionDomain::getPermissions and ProtectionDomain::staticPermissionsOnly 13. Replace PermissionCollection type argument with Object in ProtectionDomain constructors, ignore the permissions parameter, and deprecate existing constructors. Deprecate PermissionCollection for removal. 14. Create a new constructor: ProtectionDomain(CodeSource cs, ClassLoader cl, Principal[] p). 15. Create a new factory method ProtectionDomain::newInstance(Principal[] p), to allow a weak cache of ProtectionDomain instances for each Principal[], to be utilised by SubjectDomainCombiner to avoid unnecessary duplication of objects. This is an optimization for AccessControlContext::equals and ::hashCode methods. Using a cache of AccessControlContext, it is possible to avoid rechecking authorization that has already been checked. For example, when using an Executor with many tasks, all with the same AccessControlContext, you only need to check once and return the same result for subsequent checks. This is an optimization I have used previously to great effect. To clarify what an *unprivileged* AccessControlContext is: An instance of AccessControlContext, that contains a single element array, containing a ProtectionDomain, with a null ClassLoader, null Principal[] and a *non-null* CodeSource, containing a null URL. So as to distinguish between what is traditionally a JDK bootstrap ProtectionDomain and unprivileged domain after ProtectionDomain::getPermissions is removed. Stubbing of SecurityManager and Policy, for runtime backward
Re: Authorization layer API and low level access checks.
Inline. On 26/06/2021 1:46 pm, Peter Firmstone wrote: Inline below. On 26/06/2021 1:11 pm, Peter Firmstone wrote: One more proposed change inline: On 26/06/2021 12:58 pm, Peter Firmstone wrote: Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code, no longer call Permission implementations directly, instances obtained using GuardFactory, only when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods, retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner Just thinking out loud, it's possible someone might want to do perform some task without privileges enabled, that is without the Subject's principal's. In a system that grants privileges to code and principals, this is generally unnecessary, as grants are made to the combination of code and principals. However while using the doPrivileged methods is possible, to remove privileges, it would be better to provide an AccessController::doUnprivileged method instead, which erase the DomainCombiner and use an *unprivileged* AccessControlContext. Since the doPrivileged methods are utilised by other methods in AccessController, they should be made private when finally deprecated for removal. I have also just noticed a bug in AccessController.AccHolder.innocuousAcc. I need to make some clarifications here: The ProtectionDomain::getPermissions() method determines whether a domain is privileged if it contains AllPermission. Since future implementations might not use Permission's to determine privileges, and privileges may be determined by CodeSource or Principal's, a null CodeSource is used to indicate a domain belonging to the bootstrap ClassLoader. The innocuous AccessControlContext, is intended to have no permission, hence it is constructed using the two argument ProtectionDomain constructor, which causes ProtectionDomain to not consult the Policy. However, if a user obtains this ProtectionDomain and asks the Policy for the ProtectionDomain's permission's by calling Policy::getPermissions(ProtectionDomain), the Policy will return AllPermission. This is incorrect, as the ProtectionDomain contains a null PermissionCollection, my mistake. However I still propose it be changed, due to the association of a null CodeSource with bootstrap ClassLoader domains. It is generally understood that a ProtectionDomain with a null CodeSource is a system ProtectionDomain loaded by the bootstrap ClassLoader. I propose that innocuous AccessControlContext instead be given a ProtectionDomain, with a non-null CodeSource, which has a null URL. This is also considered by the Policy to be unprivileged. 8. Deprecate for removal the CodeSource::implies method. 9. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. 10. Deprecate for removal AccessController::checkPermission and AccessControlContext::checkPermission methods. 11. Undeprecate AccessController, AccessControlContext, DomainCombiner, SubjectDomainCombiner and
Re: Authorization layer API and low level access checks.
Inline below. On 26/06/2021 1:11 pm, Peter Firmstone wrote: One more proposed change inline: On 26/06/2021 12:58 pm, Peter Firmstone wrote: Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code, no longer call Permission implementations directly, instances obtained using GuardFactory, only when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods, retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner Just thinking out loud, it's possible someone might want to do perform some task without privileges enabled, that is without the Subject's principal's. In a system that grants privileges to code and principals, this is generally unnecessary, as grants are made to the combination of code and principals. However while using the doPrivileged methods is possible, to remove privileges, it would be better to provide an AccessController::doUnprivileged method instead, which erase the DomainCombiner and use an *unprivileged* AccessControlContext. Since the doPrivileged methods are utilised by other methods in AccessController, they should be made private when finally deprecated for removal. I have also just noticed a bug in AccessController.AccHolder.innocuousAcc. The innocuous AccessControlContext, is intended to have no permission, hence it is constructed using the two argument ProtectionDomain constructor, which causes ProtectionDomain to not consult the Policy. However, if a user obtains this ProtectionDomain and asks the Policy for the ProtectionDomain's permission's by calling Policy::getPermissions(ProtectionDomain), the Policy will return AllPermission. It is generally understood that a ProtectionDomain with a null CodeSource is a system ProtectionDomain loaded by the bootstrap ClassLoader. I propose that innocuous AccessControlContext instead be given a ProtectionDomain, with a non-null CodeSource, which has a null URL. This is also considered by the Policy to be unprivileged. 1. Deprecate for removal the CodeSource::implies method. 2. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. 10. Deprecate for removal AccessController::checkPermission and AccessControlContext::checkPermission methods. 11. Undeprecate AccessController, AccessControlContext, DomainCombiner, SubjectDomainCombiner and Subject::doAs methods, while deprecating for removal methods stated in items above. To clarify what an *unprivileged* AccessControlContext is: An instance of AccessControlContext, that contains a single element array, containing a ProtectionDomain, with a non null CodeSource, containing a null URL. Retention of AccessController, AccessControlContext, DomainCombiner and SubjectDomainCombiner and Subject::doAs methods. Stubbing of SecurityManager and Policy, for runtime backward compatibility. Update ProtectionDomain::implies method, to *not* consult with the Policy. Note it's possible to get access to the ProtectionDomain array contained within
Re: Authorization layer API and low level access checks.
One more proposed change inline: On 26/06/2021 12:58 pm, Peter Firmstone wrote: Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code, no longer call Permission implementations directly, instances obtained using GuardFactory, only when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods, retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner 8. Deprecate for removal the CodeSource::implies method. 9. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. 10. Deprecate for removal AccessController::checkPermission and AccessControlContext::checkPermission methods. 11. Undeprecate AccessController, AccessControlContext, DomainCombiner, SubjectDomainCombiner and Subject::doAs methods, while deprecating for removal methods stated in items above. To clarify what an *unprivileged* AccessControlContext is: An instance of AccessControlContext, that contains a single element array, containing a ProtectionDomain, with a non null CodeSource, containing a null URL. Retention of AccessController, AccessControlContext, DomainCombiner and SubjectDomainCombiner and Subject::doAs methods. Stubbing of SecurityManager and Policy, for runtime backward compatibility. Update ProtectionDomain::implies method, to *not* consult with the Policy. Note it's possible to get access to the ProtectionDomain array contained within AccessControlContext using a DomainCombiner. This is backward compatible with existing usages of JAAS and least painful method of transition for all concerned as well as allowing complete flexibility of implementation. Regards, Peter Firmstone. On 25/06/2021 3:59 pm, Peter Firmstone wrote: Thanks Dalibor, Would targeting Java 18 be practical? Also it won't take long to code a prototype, just not sure of the process. Cheers, Peter. On 24/06/2021 9:30 pm, Dalibor Topic wrote: On 24.06.2021 04:24, Peter Firmstone wrote: Thanks Andrew, For the simple case, of replacing the SecurityManager stack walk, one could use reflection. Thank you for also confirming that is not possible (or at least very unlikely) to add a GuardBuilder to Java 8, the proposal is for JDK code to use a provider mechanism, to intercept permission checks, so custom authentication layers can be implemented, this could be accepted in future versions of Java, but not existing. As it is said, there is no harm in asking. Generally speaking, adding any public APIs to a platform release after its specification has been published, is always going to be a very tall order involving the JCP, among other things. It's not really worth it, when other technical solutions, such as multi-release JARs, already exist, that alleviate the necessity. cheers, dalibor topic -- Regards, Peter Firmstone 0498 286 363 Zeus Project Services Pty Ltd.
Re: Authorization layer API and low level access checks.
Summary of Proposed Changes: 1. GuardFactory & GuardFactorySpi to provide hooks for authorization checks without SecurityManager or Policy. (Note GuardFactory should never return null and instead return a no-op Guard that hotspot can optimize out. 2. Existing Permission implementations to be obtained using GuardFactorySpi implementations, until their removal. Note that when SecurityManager is stubbed out and Permission implementations are deprecated for removal, these should no longer be provided by default, but instead need to be enabled by entries in the java.security config file, in preparation for their removal. 3. JDK code, no longer call Permission implementations directly, instances obtained using GuardFactory, only when enabled in the java.security configuration file. 4. Threads (system and virtual) updated to use a singleton *unprivileged* AccessControlContext, instead of inherited AccessControlContext, this is more appropriate for Executors, the original inherited context was designed before Executors were introduced. 5. Deprecation for removal of all Permission implementations from the JDK platform. The existing implementations of Permission introduce unnecessary complexity; they lack sufficient flexibility resulting in a proliferation of Permission grants required in policy files and some make blocking network calls. 6. Introduce a system property to change AccessController default behaviour, disable the stack walk by default, but allow it to be re-enabled with a system property, replace the stack walk array result of ProtectionDomains with an *unprivileged* AccessControlContext, the SubjectDomainCombiner can replace it with a, AccessControlContext containing a single element array, containing one ProtectionDomain with Principals. 7. AccessController::doPrivileged erases the DomainCombiner by default, deprecate these methods, retain doPrivilegedWithCombiner methods that preserve the SubjectDomainCombiner. Developers should replace their doPrivileged methods with doPrivilegedWithCombiner 8. Deprecate for removal the CodeSource::implies method. 9. Give unique ProtectionDomain's with a meaninful CodeSource to Java modules mapped to the boot loader, rather than using a Shared ProtectionDomain with a null CodeSource. To clarify what an *unprivileged* AccessControlContext is: An instance of AccessControlContext, that contains a single element array, containing a ProtectionDomain, with a non null CodeSource, containing a null URL. Retention of AccessController, AccessControlContext, DomainCombiner and SubjectDomainCombiner and Subject::doAs methods. Stubbing of SecurityManager and Policy, for runtime backward compatibility. Update ProtectionDomain::implies method, to *not* consult with the Policy. Note it's possible to get access to the ProtectionDomain array contained within AccessControlContext using a DomainCombiner. This is backward compatible with existing usages of JAAS and least painful method of transition for all concerned as well as allowing complete flexibility of implementation. Regards, Peter Firmstone. On 25/06/2021 3:59 pm, Peter Firmstone wrote: Thanks Dalibor, Would targeting Java 18 be practical? Also it won't take long to code a prototype, just not sure of the process. Cheers, Peter. On 24/06/2021 9:30 pm, Dalibor Topic wrote: On 24.06.2021 04:24, Peter Firmstone wrote: Thanks Andrew, For the simple case, of replacing the SecurityManager stack walk, one could use reflection. Thank you for also confirming that is not possible (or at least very unlikely) to add a GuardBuilder to Java 8, the proposal is for JDK code to use a provider mechanism, to intercept permission checks, so custom authentication layers can be implemented, this could be accepted in future versions of Java, but not existing. As it is said, there is no harm in asking. Generally speaking, adding any public APIs to a platform release after its specification has been published, is always going to be a very tall order involving the JCP, among other things. It's not really worth it, when other technical solutions, such as multi-release JARs, already exist, that alleviate the necessity. cheers, dalibor topic
Re: Authorization layer API and low level access checks.
The more I think about it, allowing Thread to use a singleton immutable unprivileged AccessControlContext instead of the inherited context is the right thing to do, it achieves the original goal of avoiding privilege escalation, limits the the size of the context that needs to be checked and allows simple support for virtual threads. The AccessController.doPrivileged method allows code to make privileged actions. The way to implement it, for compatible transition would be: 1. Implement it first in virtual threads. 2. When stubbing out SecurityManager, change system threads to also use the singleton unprivileged context, instead of the inherited context, which must be calculated for each thread at creation time. 3. Alternative option to item 2, is to make generic grants in policy files for affected threads (which inherited privileged context). I recently generated some principle of least privilege policy files for tests: https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuresharedvm.policy.new https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuretest.policy.new https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecurephoenix.policy.new For the generation of these policy files, a properties file was provided, to populate the policy files with properties, to replace local and platform specific paths and file names. Note how many permissions are granted to code and principal's. This ensures that other code cannot use the principal's thread for privileged escalation, and code cannot perform certain tasks without a logged in Subject. This is how we prevent deserialization (not Java deserialization) of untrusted data in our case, we have DeserializationPermission. So not only do we ensure there's a logged in Subject, that's providing the data, but we are also restricting the code that is allowed to parse it. Our deserialization uses constructors to validate invariants but, we still avoid using it to process untrusted data. One pain point is SocketPermission, which doesn't allow IP Address subnet wild cards, hence the use of unlimited IP Address wild cards. It's generally preferable not to use domain names in SocketPermission, due to blocking DNS calls, personally I'd like to replace that with RFC3986 normalization. Note that the JGDMS SecurityManager and Policy implementations are performant and scalable, all hotspots in JGDMS are JDK native methods (Socket's basically). The use of virtual threads, would provide a significant scalability improvement for JGDMS. If we could get the proposed GuardBuilder & GuardBuilderSpi happening (so developers are freed from the current Permission implementations) as well as the proposed changes to thread AccessControlContext below, we would have the best authorization layer available. We can still stub out SecurityManager and remove the Policy and Permission implementations, to reduce the maintenance burden for OpenJDK developers. The reality is, the overall result for us, will be much better, if we can retain AccessController and AccessControlContext for the following reasons: 1. Allowing grants to be made to code and principals, to prevent parsing of untrusted data, while limiting the scope of those grants (refer to 3). 2. Preserving current JAAS functionality, to authenticate and secure connections. 3. Limiting or preventing viral authorization checks from spreading to an excessive number of ProtectionDomains (viral Permissions). For the libraries and JVM code that use doPrivileged will continue to function using common API's. 4. To enable developers to implement an authorization layer. While this may be a small proportion of overall projects, the projects that do are usually significant. We don't require SecurityManager, a Policy or Permission implementations to implement an authorization layer and these components are the majority of the maintenance burden for OpenJDK, as far as I can tell at least. Basic components required for effective authorization layer implementations: 1. Guard, GuardBuilder and GuardBuilderSpi (or equivalent). 2. AccessController, AccessControlContext and DomainCombiner (These are difficult to re-implement in a Java version compatible manner, and re-implementations would not have the benefits of JDK support for AccessController.doPrivileged, or Thread context, which limits viral authorization checks). 3. ProtectionDomain, CodeSource and Principal 4. JAAS, Subject and LoginModule. 5. GSS-API/Kerberos, JCA, JCE and JSSE. -- Regards, Peter Firmstone On 24/06/2021 11:50 am, Peter Firmstone wrote: Clarification inline below. On 24/06/2021 11:03 am, Peter Firmstone wrote: Hi Alan, It is important to understand the reason for the inherited AccessControlContext, in order to consider alternatives. The motivation for inherited context, was simply to avoid privilege
Re: Authorization layer API and low level access checks.
Thanks Remi, We're still building on 8, for CORBA-IIOP stubs, but will look into this when we've found an alternative IIOP stub compiler. -- Regards, Peter On 23/06/2021 8:02 pm, Remi Forax wrote: - Mail original - De: "Andrew Dinn" À: "Peter Firmstone" , "discuss" Cc: "security-dev" Envoyé: Mercredi 23 Juin 2021 11:19:42 Objet: Re: Authorization layer API and low level access checks. OHi Peter, n 23/06/2021 04:02, Peter Firmstone wrote: 1. StackWalker - Can stack walker be back ported to Java 8? The right place to ask about this is the jdk8u updates project list. However, you probably don't need to ask there because the answer is almost certainly going to be a very loud no. JDK8u is in long term maintenance mode. The goal of the updates project for that release is to fix security issues and critical bugs *and nothing else* so that existing deployments remain stable as far as possible. Except when required to meet those goals backporting of new functionality is done only under exceptional circumstances. The only recent examples of new function backports that I am aware of have involved merging up functionality from downstream releases in order to 1) unify the platform and 2) enable downstream contributors to help to maintain a single, standard release i.e. highly exceptional cases where there was a problem for existing users. Your request, by contrast, is exactly the sort of case that maintainers are trying to avoid -- it will introduce change with no gain and the potential of breakage for the vast majority of users. If you want to deal with deployments pre and post removal of the Authorization support that you currently rely on I suggest you consider doing that by using a multi-release implementation and package it using the multi-release jar format. If you don't like the idea of multi-release jars you can still implement a standard jar format solution using a provider model. However, you will still need to build the alternative provider jars using the relevant JDK releases so that different providers can rely on different JDK capabilities.. Technically, you may not need several JDKs because you can ask javac to behave as if it was compiling like a previous JDK using the option "--release" (this option is also available with Maven and Gradle). I believe that compiling as the release 8 will be supported up to Java 23. regards, Andrew Dinn --- Red Hat Distinguished Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill regards, Rémi
Re: Authorization layer API and low level access checks.
Thanks Andrew, For the simple case, of replacing the SecurityManager stack walk, one could use reflection. Thank you for also confirming that is not possible (or at least very unlikely) to add a GuardBuilder to Java 8, the proposal is for JDK code to use a provider mechanism, to intercept permission checks, so custom authentication layers can be implemented, this could be accepted in future versions of Java, but not existing. As it is said, there is no harm in asking. The advantages of being able to address issues with Permission implementations and customise, for example, by providing a replacement for SocketPermission, that doesn't call DNS, and allows wild cards for subnets, would be significant for the simplification of authorization. So developers might hope to be able to implement a significantly improved authorization layer for a future version of Java, provided we have some basic things like JVM hooks for access checks. -- Regards, Peter Firmstone On 23/06/2021 7:19 pm, Andrew Dinn wrote: OHi Peter, n 23/06/2021 04:02, Peter Firmstone wrote: 1. StackWalker - Can stack walker be back ported to Java 8? The right place to ask about this is the jdk8u updates project list. However, you probably don't need to ask there because the answer is almost certainly going to be a very loud no. JDK8u is in long term maintenance mode. The goal of the updates project for that release is to fix security issues and critical bugs *and nothing else* so that existing deployments remain stable as far as possible. Except when required to meet those goals backporting of new functionality is done only under exceptional circumstances. The only recent examples of new function backports that I am aware of have involved merging up functionality from downstream releases in order to 1) unify the platform and 2) enable downstream contributors to help to maintain a single, standard release i.e. highly exceptional cases where there was a problem for existing users. Your request, by contrast, is exactly the sort of case that maintainers are trying to avoid -- it will introduce change with no gain and the potential of breakage for the vast majority of users. If you want to deal with deployments pre and post removal of the Authorization support that you currently rely on I suggest you consider doing that by using a multi-release implementation and package it using the multi-release jar format. If you don't like the idea of multi-release jars you can still implement a standard jar format solution using a provider model. However, you will still need to build the alternative provider jars using the relevant JDK releases so that different providers can rely on different JDK capabilities.. regards, Andrew Dinn --- Red Hat Distinguished Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill
Re: Authorization layer API and low level access checks.
Clarification inline below. On 24/06/2021 11:03 am, Peter Firmstone wrote: Hi Alan, It is important to understand the reason for the inherited AccessControlContext, in order to consider alternatives. The motivation for inherited context, was simply to avoid privilege escalation, prior to Executors. Whenever a permission check is made, the DomainCombiner, combines the inherited context, with the thread's current context, in case there are any less privileged domains in the inherited context. But there is an alternative, higher performance option, that avoids privilege escalation for executors as well. A ProtectionDomain with a null CodeSource has AllPermission, while a ProtectionDomain that contains a CodeSource with a null URL has only the Permission's given to it when created, or to blanket grant statements in policy files. Rather than inherit context from the calling thread, all threads upon creation could be initialized with one shared immutable unprivileged AccessControlContext, containing a single element array, with a ProtectionDomain, containing a CodeSource with a null URL. Code cannot assume that calling code is privileged, hence the AccessController.doPrivileged method, so an unprivileged context could replace system threads inherited context as well. There will be some minor impacts in older code where developers create a system thread for cleanup tasks or other things, but nothing that couldn't be worked around, until it can be addressed properly. This is an existential moment for Java authorization, as a developer with extensive use of Java authorization, I would most certainly welcome this change. This would be a simplification that enhances security. This is far more preferable than an inherited AccessControlContext as it eliminates any risk that Executor tasks present, where domains in the context that creates Callable or Runnable, may not be in the inherited thread context. JEP 411, presents an opportunity to address it. A use case: I would like to use virtual threads, in executors, to make blocking secure network connections, so I don't consume too many system threads. When network failures occur, the number of threads created increase significantly, as blocked threads waiting on network are no longer available to the executor. All our executor tasks are wrapped, with AccessControlContext, using Executors::callable(PrivilegedAction), we do this to capture the Subject, and to grant SocketPermission (to Principles and CodeSource) to make secure network calls from one node to another. Across the network, the user Subject's Principals are preserved, from the thread in the client to the thread in the server during authentication. DeserializationPermission is granted to the user Principal's and CodeSource in the server, so that the code cannot perform deserialization (not to be confused with Java serialization) without an authenticated user. The authenticated user represents the domain from which data to be deserialized originates. Personally I would like to see AccessController and AccessControlContext retained, and all threads modified to be initialized with a single shared immutable unprivileged AccessControlContext, rather than an inherited AccessControlContext in system threads and virtual threads that do not support any permissions at all. All threads except bootstrap threads in the JVM, obviously they would need to be privileged. -- Regards, Peter Firmstone
Re: Authorization layer API and low level access checks.
Hi Alan, It is important to understand the reason for the inherited AccessControlContext, in order to consider alternatives. The motivation for inherited context, was simply to avoid privilege escalation, prior to Executors. Whenever a permission check is made, the DomainCombiner, combines the inherited context, with the thread's current context, in case there are any less privileged domains in the inherited context. But there is an alternative, higher performance option, that avoids privilege escalation for executors as well. A ProtectionDomain with a null CodeSource has AllPermission, while a ProtectionDomain that contains a CodeSource with a null URL has only the Permission's given to it when created, or to blanket grant statements in policy files. Rather than inherit context from the calling thread, all threads upon creation could be initialized with one shared immutable unprivileged AccessControlContext, containing a single element array, with a ProtectionDomain, containing a CodeSource with a null URL. Code cannot assume that calling code is privileged, hence the AccessController.doPrivileged method, so an unprivileged context could replace system threads inherited context as well. There will be some minor impacts in older code where developers create a system thread for cleanup tasks or other things, but nothing that couldn't be worked around, until it can be addressed properly. This is an existential moment for Java authorization, as a developer with extensive use of Java authorization, I would most certainly welcome this change. This would be a simplification that enhances security. This is far more preferable than an inherited AccessControlContext as it eliminates any risk that Executor tasks present, where domains in the context that creates Callable or Runnable, may not be in the inherited thread context. JEP 411, presents an opportunity to address it. A use case: I would like to use virtual threads, in executors, to make blocking secure network connections, so I don't consume too many system threads. When network failures occur, the number of threads created increase significantly, as blocked threads waiting on network are no longer available to the executor. All our executor tasks are wrapped, with AccessControlContext, using Executors::callable(PrivilegedAction), we do this to capture the Subject, and to grant SocketPermission (to Principles and CodeSource) to make secure network calls from one node to another. Across the network, the user Subject's Principals are preserved, from the thread in the client to the thread in the server during authentication. DeserializationPermission is granted to the user Principal's and CodeSource in the server, so that the code cannot perform deserialization (not to be confused with Java serialization) without an authenticated user. The authenticated user represents the domain from which data to be deserialized originates. Personally I would like to see AccessController and AccessControlContext retained, and all threads modified to be initialized with a single shared immutable unprivileged AccessControlContext, rather than an inherited AccessControlContext in system threads and virtual threads that do not support any permissions at all. -- Regards, Peter Firmstone On 23/06/2021 4:34 pm, Alan Bateman wrote: On 23/06/2021 04:02, Peter Firmstone wrote: Note: I'm not sure how to replace an inherited AccessControlContext (with a new implementation based on StackWalker functionality) at thread creation time, as it must be created when threads are created, possibly by using ThreadFactory everywhere, but this doesn't cover all threads. How to cater for virtual threads? I don't think the inherited AccessControlContext is widely known or even clearly specified. In any case, virtual threads do not want to be burdened with this field. For now they are specified to not support any permissions. The FJ common pool is another example, the threads don't have any permissions either (see FJP class description has more on that). -Alan
Re: Authorization layer API and low level access checks.
- Mail original - > De: "Andrew Dinn" > À: "Peter Firmstone" , "discuss" > > Cc: "security-dev" > Envoyé: Mercredi 23 Juin 2021 11:19:42 > Objet: Re: Authorization layer API and low level access checks. > OHi Peter, > > n 23/06/2021 04:02, Peter Firmstone wrote: >> 1. StackWalker - Can stack walker be back ported to Java 8? > > The right place to ask about this is the jdk8u updates project list. > However, you probably don't need to ask there because the answer is > almost certainly going to be a very loud no. > > JDK8u is in long term maintenance mode. The goal of the updates project > for that release is to fix security issues and critical bugs *and > nothing else* so that existing deployments remain stable as far as > possible. Except when required to meet those goals backporting of new > functionality is done only under exceptional circumstances. > > The only recent examples of new function backports that I am aware of > have involved merging up functionality from downstream releases in order > to 1) unify the platform and 2) enable downstream contributors to help > to maintain a single, standard release i.e. highly exceptional cases > where there was a problem for existing users. Your request, by contrast, > is exactly the sort of case that maintainers are trying to avoid -- it > will introduce change with no gain and the potential of breakage for the > vast majority of users. > > If you want to deal with deployments pre and post removal of the > Authorization support that you currently rely on I suggest you consider > doing that by using a multi-release implementation and package it using > the multi-release jar format. If you don't like the idea of > multi-release jars you can still implement a standard jar format > solution using a provider model. However, you will still need to build > the alternative provider jars using the relevant JDK releases so that > different providers can rely on different JDK capabilities.. Technically, you may not need several JDKs because you can ask javac to behave as if it was compiling like a previous JDK using the option "--release" (this option is also available with Maven and Gradle). I believe that compiling as the release 8 will be supported up to Java 23. > > regards, > > > Andrew Dinn > --- > Red Hat Distinguished Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill regards, Rémi
Re: Authorization layer API and low level access checks.
OHi Peter, n 23/06/2021 04:02, Peter Firmstone wrote: 1. StackWalker - Can stack walker be back ported to Java 8? The right place to ask about this is the jdk8u updates project list. However, you probably don't need to ask there because the answer is almost certainly going to be a very loud no. JDK8u is in long term maintenance mode. The goal of the updates project for that release is to fix security issues and critical bugs *and nothing else* so that existing deployments remain stable as far as possible. Except when required to meet those goals backporting of new functionality is done only under exceptional circumstances. The only recent examples of new function backports that I am aware of have involved merging up functionality from downstream releases in order to 1) unify the platform and 2) enable downstream contributors to help to maintain a single, standard release i.e. highly exceptional cases where there was a problem for existing users. Your request, by contrast, is exactly the sort of case that maintainers are trying to avoid -- it will introduce change with no gain and the potential of breakage for the vast majority of users. If you want to deal with deployments pre and post removal of the Authorization support that you currently rely on I suggest you consider doing that by using a multi-release implementation and package it using the multi-release jar format. If you don't like the idea of multi-release jars you can still implement a standard jar format solution using a provider model. However, you will still need to build the alternative provider jars using the relevant JDK releases so that different providers can rely on different JDK capabilities.. regards, Andrew Dinn --- Red Hat Distinguished Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill
Re: Authorization layer API and low level access checks.
On 23/06/2021 04:02, Peter Firmstone wrote: Note: I'm not sure how to replace an inherited AccessControlContext (with a new implementation based on StackWalker functionality) at thread creation time, as it must be created when threads are created, possibly by using ThreadFactory everywhere, but this doesn't cover all threads. How to cater for virtual threads? I don't think the inherited AccessControlContext is widely known or even clearly specified. In any case, virtual threads do not want to be burdened with this field. For now they are specified to not support any permissions. The FJ common pool is another example, the threads don't have any permissions either (see FJP class description has more on that). -Alan
Authorization layer API and low level access checks.
Java developers such as myself need a light weight API that allows developers to continue to support authorization and access controls, without dictating how that should be implemented or whether these controls are fine grained, course grained, based solely on user authorization or also includes code authorization. SecurityManager has been deprecated, we need to commence removal of dependencies on deprecated Java API's, however we are unable to make a decision on how to proceed without understanding the level of support that OpenJDK will provide for an authorization layer in future. (If this is zero, we at least need to know). Currently there is no such API that allows developers who require an authorization layer to continue to supporting Java 8 as well future versions Java with one development codebase. It's a non goal of this to debate the need for cross version support. I simply wish to open discussions on alternatives and whether OpenJDK is considering them. SecurityManager API low level functionality replacements: 1. StackWalker - Can stack walker be back ported to Java 8? 2. Permission checks - Can we have low level Guard service hooks to replace existing permission checks? Note: I'm not sure how to replace an inherited AccessControlContext (with a new implementation based on StackWalker functionality) at thread creation time, as it must be created when threads are created, possibly by using ThreadFactory everywhere, but this doesn't cover all threads. How to cater for virtual threads? For replacement of permission checks, I propose using a Guard service authorization API (feel free to propose alternatives). The proposed authorization layer API would utilize the existing Provider Service mechanism to register authorization layer hooks, for use in permission checks by JDK code, and library code that implements their own Permission's: GuardFactory runtimeGuardFactory = GuardFactory.getInstance("RUNTIME"); Guard createClassLoader = runtimeGuardFactory.orders("createClassLoader", null); // Permission check createClassLoader.check(); Guard exitVM = runtimeGuardFactory.orders("exitVM", null); exitVM.check(); GuardFactory socketGuardFactory = GuardFactory.getInstance("SOCKET"); // Permission check socketGuardFactory.orders(host, action).check(); GuardFactory fileGuardFactory = GuardFactory.getInstance("FILE"); fileGuardFactory.orders(path, actions).check(); Guard service hooks, are based on existing Permission types (independent instances to avoid circular deadlocks), developers only need implement those relevant to them and may only use checks for users if they wish: "AWT" "FILE" "SERIALIZABLE" "MANAGEMENT" "REFLECT" "RUNTIME" "NET" "SOCKET" "URL" "FILE-LINK" "SECURITY" "SQL" "LOGGING" "PROPERTY" "MBEAN" "MBEAN-SERVER" "MBEAN-TRUST" "SUBJECT-DELEGATION" "TLS" "AUTH" "KERBEROS-DELEGATION" "KERBEROS-SERVICE" "PRIVATE-CREDENTIAL" "AUDIO" "JAXB" "WEB-SERVICE" I would like to suggest adding a new provider type: "PARSE-DATA" - To be called by any code about to parse data, eg deserialization, XML, JSON, SQL, etc. The use case for this is for servers to grant it to authenticated users (user supplied input data), so that it can only be performed following user authentication. Existing Permission implementations -- Regards, Peter Firmstone