Re: Authorization layer API and low level access checks.

2021-07-10 Thread Peter Firmstone

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.

2021-06-30 Thread Peter Firmstone

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

2021-06-27 Thread Peter Firmstone
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

2021-06-26 Thread Peter Firmstone


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

2021-06-25 Thread Peter Firmstone

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.

2021-06-25 Thread Peter Firmstone

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.

2021-06-25 Thread Peter Firmstone

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.

2021-06-25 Thread Peter Firmstone

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.

2021-06-25 Thread Peter Firmstone

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.

2021-06-25 Thread Peter Firmstone
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.

2021-06-24 Thread Peter Firmstone

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.

2021-06-23 Thread Peter Firmstone

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.

2021-06-23 Thread Peter Firmstone

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.

2021-06-23 Thread Peter Firmstone

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.

2021-06-23 Thread Remi Forax
- 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.

2021-06-23 Thread Andrew Dinn

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.

2021-06-23 Thread Alan Bateman

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.

2021-06-22 Thread Peter Firmstone
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