I have been pondering whether to add the following method to RevocablePolicy:

public Collection<PermissionGrant> getPermissionGrants(boolean recursive);

This method could enable a developer to query individual PermissionGrants before revoking, however since PermissionGrant implementations are private, a developer can never be 100% sure of the effect of removing it. For instance a PermissionGrant may apply generally, not just to the ProtectionDomain concerning the developer.

In fact, it is the PermissionGrant itself, or the entity that created it, that is best suited to determining if and when it should be revoked.

For example, if a Subject is granted a Permission to access a resource only for 24 hours, then after this period a PermissionGrant can return isVoid() if queried.

However, since our new SecurityManager caches the results of permission checks, the permission will continue to remain granted until the Policy is refereshed. Upon refresh, all void PermissionGrant's are automatically removed by the Policy.

A user developer can use decorators, to add functionality to PermissionGrant, and intercept the isVoid() method based on conditions.

So in reality, even the revoke method is not required:

public boolean revoke(PermissionGrant p);

Instead it makes much more sense to use Event notifications and decorators to effect revocation, in this case a PermissionGrant decorator can be notified of an event and Policy.refresh() called, the Policy itself removes the PermissionGrant.

PermissionGrants may be used to grant permissions temporarily, for example place a cap on network traffic for Subjects, refreshed monthly, daily or weekly.

A DelegateSocket (Delegates will be distributed separately) might notify some kind of grant manager that in turn notifies the PermissionGrant that conditions have changed and also refresh the policy. The PermissionGrant may still be valid and doesn't need to be removed from the policy, the grant manager may notify the PermissionGrant when conditions have returned to normal, again the policy must be refreshed when conditions change.

The Policy.refresh() call is non blocking with our new policy providers and SecurityManager cache, allowing security policy checks to continue concurrently while a refresh is in progress.

Depending on conditions, it the developer may by satisfied to simply refresh the policy periodically independent of conditions, but this decision is left to implementers.

Regards,

Peter.


/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.river.api.security;

import java.security.Permission;
import java.security.Principal;
import net.jini.security.policy.DynamicPolicy;

/**
* <p>
* RevocablePolicy, is a Java Security Policy Provider that supports
* Runtime Dynamic addition and removal of PermissionGrant's
* </p><p>
* Warning: Not all Permission's are truly revocable, while any Permission can * be dynamically added and later removed from this policy, many JVM Permission
* implementations are used in ways that allow references to escape
* </p><p>
* To quote Tim Blackman, from river-dev:
* </p><p><CITE>
* I remember talking with Bob and Mike Warres about this.  The problem with
* removing permission grants is that when code is granted a permission,
* it can very likely squirrel away something -- an object, or another
* capability available through the granted permission -- that will permit
* it to perform the same operation again without the JVM checking for
* the permission again.
* </CITE>
* </p><p>
* In order for a Permission to be fully revoked, the permission must be
* used to guard methods only, not Objects or their creation.  A Security
* Delegate, may be used as a wrapper with an identical interface to the object * it protects, a new Permission class must be implemented, for the Delegate's
* use, in a checkPermission call, to protect access to the underlying
* object's method. If an existing JVM Permission guards the underlying object, * the delegate needs to be given the standard JVM Permission. DelegatePermission
* has been created for the purpose of encapsulating an existing Permission.
* </p><p>
* The ability to revoke a Permission fully is intended for smart proxy's to
* be given some trust temporarily, so that objects received from the smart proxy * by a client cannot be used to continue gathering and sending information to
* a remote server after the proxy has been discarded.
* </p><p>
* A list of standard Java Permission's that are confirmed safely
* revocable will be provided here.
* </p>
* @author Peter Firmstone
* @see java.security.Policy
* @see java.security.ProtectionDomain
* @see java.security.AccessController
* @see java.security.DomainCombiner
* @see java.security.AccessControlContext
* @see java.security.Permission
* @see PermissionGrant
* @see DelegatePermission
*/
public interface RevocablePolicy extends DynamicPolicy {
   /**
    * Revokes a specific PermissionGrant from the Policy.
    *
* Caveat: Not all Permission's once granted can be revoked. When a Permission
    * is checked, prior to passing a reference to a caller, that reference
* has escaped any further Permission checks, meaning that the Permission
    * cannot be revoked for the caller holding a reference.
    *
* Note that after revocation, the caller should call Policy.getPermissions
    * to determine if the proxy has no or minimal permissions.  If the
* proxy still retains permission, the caller should throw a SecurityException.
    *
    * @param p
    * @return true if successful
    */
   public boolean revoke(PermissionGrant p);
/**
    * A dynamic grant.
    * @param p
    * @return true if successful
    */
   public boolean grant(PermissionGrant p);
   /**
    *
    * @return true - If Revoke supported by underlying policy.
    */
   public boolean revokeSupported();
}

Reply via email to