<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Apologies for multiple earlier emails, please ignore and read
      this instead.</p>
    <p>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.<br>
    </p>
    <p>Summary of Proposed Changes:</p>
    <ol>
      <li>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.<br>
      </li>
      <li>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.<br>
      </li>
      <li>JDK code to no longer call Permission implementations
        directly, instances obtained using GuardFactory, when enabled in
        the java.security configuration file.<br>
      </li>
      <li>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.</li>
      <li>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.<br>
      </li>
      <li>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.  <br>
      </li>
      <li>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.<br>
      </li>
      <li>Deprecate for removal the CodeSource::implies method.</li>
      <li>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.</li>
      <li>Deprecate for removal AccessController::checkPermission and
        AccessControlContext::checkPermission methods.</li>
      <li>Undeprecate AccessController, AccessControlContext,
        DomainCombiner, SubjectDomainCombiner and Subject::doAs methods,
        while deprecating for removal methods stated in items above.</li>
      <li>Deprecate for removal ProtectionDomain::implies,
        ProtectionDomain::getPermissions and
        ProtectionDomain::staticPermissionsOnly</li>
      <li>Replace PermissionCollection type argument with Object in
        ProtectionDomain constructors, ignore the permissions parameter,
        and deprecate existing constructors.   Deprecate
        PermissionCollection for removal.<br>
      </li>
      <li>Create a new constructor: ProtectionDomain(CodeSource cs,
        ClassLoader cl, Principal[] p).</li>
      <li>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.<br>
      </li>
    </ol>
    <p>To clarify what an *unprivileged* AccessControlContext is:</p>
    <blockquote>
      <p>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.<br>
      </p>
      <p>So as to distinguish between what is traditionally a JDK
        bootstrap ProtectionDomain and unprivileged domain after
        ProtectionDomain::getPermissions is removed.<br>
      </p>
    </blockquote>
    <blockquote> </blockquote>
    <p>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.<br>
    </p>
    <p>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.</p>
    <p>Regards,</p>
    <p>Peter Firmstone.<br>
    </p>
    <div class="moz-cite-prefix">On 25/06/2021 3:59 pm, Peter Firmstone
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:2f315680-1cdb-1694-34a3-95312bf42ca7@zeus.net.au">Thanks
      Dalibor, <br>
      <br>
      Would targeting Java 18 be practical? <br>
      <br>
      Also it won't take long to code a prototype, just not sure of the
      process. <br>
      <br>
      Cheers, <br>
      <br>
      Peter. <br>
      <br>
      <br>
      On 24/06/2021 9:30 pm, Dalibor Topic wrote: <br>
      <blockquote type="cite">On 24.06.2021 04:24, Peter Firmstone
        wrote: <br>
        <blockquote type="cite">Thanks Andrew, <br>
          <br>
          For the simple case, of replacing the SecurityManager stack
          walk, one could use reflection. <br>
          <br>
          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. <br>
        </blockquote>
        <br>
        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.
        <br>
        <br>
        cheers, <br>
        dalibor topic <br>
        <br>
      </blockquote>
    </blockquote>
  </body>
</html>