The Access Control Manager API

Document #: ??
Authors: Jaap-Henk Hoepman (CWI)
Editor: (none)
Reviewer: (none)
Status: Draft Version. 1, SEMPER internal


Introduction

For potentially dangerous, compromising or undesirable operations, SEMPER managers must declare a capability. Such a capability must be verified each time the corresponding action is performed. The Access Control Manager (ACM) provides the necessary tools to manage such capabilities. The design described here is based on the concepts developed in the SEMPER activity paper 221CW021: Initial Design of the Access Control Manager. However, the interface has changed considerably since then.

In its simplest form, verifying a capability involves asking the user whether the capability is (still) valid. To avoid an avalanche of questions when a high level operation triggers many low level ones, high level managers can declare roles that can contain many capabilities. Roles are either locked or unlocked; depending on their type they may require passwords to be unlocked. If a simple capability belongs to an unlocked role, it is considered valid. A capability may belong to several roles. If only one of these roles is unlocked, the capability is (potentially) valid. If not, it is invalid.

Just as there are different types of roles (that differ in they way they are unlocked, and hence provide a certain level of security), there are different types of capabilities as well. Simple capabilities are always valid (as long as they belong to an unlocked role); other capabilities may be valid only if a pass phrase was entered that has not expired yet.

The Access Control Manager does not restrict the types of roles and/or capabilities. Instead it declares two abstract classes Role and Capability that provide the core interfaces and implement the basic functionality needed to perform access control. Some fully functional (i.e. non-abstract) default roles and capabilities are declared as subclasses. The advantages of this method is that other managers can declare other types of roles or capabilities specific to their needs.

Roles

A role is either locked or unlocked. When a role is locked, the user may be asked to unlock it. The method islocked() checks whether the role is locked. The method lock() locks the role. The method unlock() asks the user to unlock the role (possibly asking for some form of authentication).

All roles store a string description describing the role, from which the user can deduce what kind of capabilities are stored in this role, and therefore which kind of actions she allows if she unlocks the role. The description is specified when creating the role.

The ACM keeps track of all roles that currently exist. These can be queried through the class method Role.getAllRoles() (which, for example, is necessary if the user wishes to lock all existing roles). When a new role is created, a reference to it is automatically added to this database of current roles. Therefore, before destroying the last external reference to a role, it must be removed from the database using the finish() method. Otherwise the reference in the database would prevent the role from being garbage collected (and it would erroneously show up in the list of all existing roles). The ACM currently implements three types of roles:

UnlockedRole
Roles in this class are always unlocked. To create a role, use
new UnlockedRole('desc').
islocked() always returns false; unlock() should not be called.
OrdinaryRole
Roles in this class can be unlocked without using any form of authentication. When locked, the user is asked to unlock it. To create a role, use
new OrdinaryRole('desc').
SecureRole
Roles in this class can be unlocked only by entering a password. To create a role, use
new SecureRole('desc','passwd').
'passwd' is the encrypted password against which to match the password entered by the user.
Other conceivable roles may be ones that are automatically locked after a certain timeout. If the need arises, let me know.

Role class structure

java.lang.Object
   |
   +----semper.access.Role
           |
           +----semper.access.UnlockedRole
           |
           +----semper.access.OrdinaryRole
           |
           +----semper.access.SecureRole

Capabilities

Capabilities are created by the different Semper managers. A valid capability allows a manager to execute the associated action (as long as it belongs to an unlocked role as well).

All capabilities store a string description describing the capability, from which the user can deduce what kind of action is associated with the capability. The description is specified when creating the capability.

Capabilities must be belong to one or more (unlocked) roles to be of any use at all. The Capability class defines the following methods to manage membership of roles:

addToRole(Role r)
Add the capability to a role.
removeFromRole(Role r)
Remove the capability from a role. If the capability is not a member, nothing happens.
findUnlockedRole()
Check whether the capability belongs to any unlocked role. If the capability does not belong to an unlocked role, the user is first prompted to unlock one of the roles the capability belongs to. If the user does not unlock any of these roles, this method returns false. This is an internal function (used by AccessMan in verifyCapability()).

Each capability class must specify a protected method isValid() that can be used by AccessMan to implement verifyCapability. isValid checks whether the capability is (still) valid. Depending on the type of capability that instantiates this method, this may always return true or involve the (re-)entering of a password (if it expired). This method is not accessible form outside the package (so other packages shouldn't/cannot depend on this). This implementation may change in the future.

The ACM currently implements two types of capabilities:

SimpleCapability
Capabilities in this class are always valid. To create a new simple capability use
new SimpleCapability('desc')
isValid() always returns true.
PassWordCapability
Capabilities in this class are only valid if a valid password was entered sufficiently recently. To create a new password capability use
new PassWordCapability('desc','passwd','timeout')
Where 'passwd' is the encrypted password against which to match the password entered by the user. 'timeout' is the time (in milliseconds) after which the password expires.
Other types of capabilities are easily added to the system.

Capability class structure

java.lang.Object
   |
   +----semper.access.Capability
           |
           +----semper.access.SimpleCapability
           |
           +----semper.access.PassWordCapability

AccessMan

The class' semper.access.AccessMan sole purpose is to provide a more or less secure implementation of the method verifyCapability to verify whether a capability is valid. Before performing an action, a manager must call verifyCapability(capa), where capa is the associated capability.

verifyCapability() will check whether the capability belongs to any unlocked roles, and if so, verify whether the capability is valid. If the capability does not belong to any unlocked roles, the user is prompted to unlock one of these first. If the method is still not a member of any unlocked roles, or if the capability is not valid, verifyCapability returns false; otherwise it returns true.

verifyCapability is a static, class, method. No objects of class AccessMan need to be instantiated.

Usage of the ACM in other blocks

As an example of how to use the ACM consider the following piece of code (or consult the test files in the ./Test directory. The following manager implements two actions (to say `Ni!' or to say `Ekki-ekki!'), and wishes to guard those using the ACM. First two roles are defined (presumably by some other, higher-layer manager).
unlocked_role = new UnlockedRole("An unlocked role") ;
secure_role = new SecureRole("A secure role","SECRET") ;
	// with password "SECRET"; unencrypted in the current implementation..
Next, the manager defines two capabilities associated with the actions.
simple_capa = new SimpleCapability("Allows to say Ni!") ;
password_capa = new PassWordCapability("Allows to say Ekki-ekki!","123",10000) ;
	// with password "123" and a timeout of 10000 milliseconds..
And adds them to the roles.
simple_capa.addToRole(secure_role) ;
password_capa.addToRole(unlocked_role) ;
Now the original actions are guarded with the capabilities using the following piece of code.
if (AccessMan.verifyCapability(password_capa))
  System.out.println("-> Ekki-ekki! ")
if (AccessMan.verifyCapability(simple_capa))
  System.out.println("-> Ni! ")
By virtue of the first guard, the user is requested to enter the password for the capability (i.e. "123"). This capability belongs to an unlocked role; therefore the user does not have to unlock any role to enable the first action. To enable the second action, the user must unlock the secure role (i.e. with password "SECRET"). This time, nothing has to be done to make the capability valid, because it is valid by default.

Interaction with the user

The ACM interacts with the user when roles need to be unlocked, or when pass phrases have to be entered for certain capabilities. Currently, this involves standard input/output. In future, Tinguin should be used for this purpose.

Interaction with other blocks

The ACM uses functions from semper.tinguin and semper.util.log.

To do

Only a simple access control scheme is currently implemented. In future, semper blocks will have to be protected from malicious use by untrusted business application through extended functionality of the ACM. No provisions have been made for that at present (except that the verify() has been moved to the AccessMan class).