Document |
231R3061: Detailed design of the Access Control Service |
Authors |
Mogens Rom Andersen (R3S) |
Editor |
Mogens Rom Andersen (R3S) |
Status |
version semper-access-revised-1, SEMPER internal |
Access control requires subjects to authenticate themselves to the objects, and requires objects to authorize subjects to perform an action.
In a typical SEMPER application several business applications can be run by several users on top of the SEMPER architecture on a single computer (see [D02]). Because these users and applications share the use of the same SEMPER services and their external data, this is a potential threat to the privacy and integrity of a single user's data. Business application will in general be downloaded when needed and the same hold for parts of the modules like the payment adapters. Thus business applications and parts of the modules cannot be completly trusted.
Therefore SEMPER provides a trust model allowing to restrict access to critical, private data and actions. In SEMPER the trust model is implemented in the Access Control Module (ACM)
SEMPER defines a small set of services making up a trusted basic distribution which are not open for external download but must be received and installed out-of-band from a trusted source. With the trusted basic distribution running all other module and busines application are open for external download introducing new versions, features etc., etc. To shielded against malicious and fake programs pretending to be something they are not, downloaded SEMPER software are packed in distributions with associated rights. (see 231R3022) All distributions must be signed with a certified signature in order to get the rights associated with them. An unsigned distribution or a distribution signed with an uncertified signature can be loaded and run in the SEMPER environment but it will be given very limited rights in the ACM.
For Business Applications (Applications) the granted rights will depend on the user running the application and the rights associated with the application itself. The rights are constructed independent from the application, but associated with its controlling class as properties during download of a distribution.
SEMPER services (Modules) follows the same schema, but the rights will only depend on the rights associated with the controlling class.
Rights are given when applications/modules registers to the ACM. Besides giving rights, the registration process will also load the class in a controlled and secure way.
In a flexible user based system as SEMPER, access control is dynamic: the right to perform an operation changes over time. Access may be granted only for a limited time. Moreover, the user can temporarily disable certain operations she is in principle allowed to perform, to prevent her from accidently executing these operations.
Rights are either persistent or non-persistent. A persistent right given to a user or application/module will survive a SEMPER session, and will be granted to the user or application/module when they register with ACM for a new session. Non-persistent rights will vanish with the SEMPER session.
A Business Application will use SEMPER Services), but the SEMPER services themselves are also registered to ACM. Several relationships can exist:
Business Applications and Modules can both act as subject or objects once they are registered. A subject gives its rights to the object, when the object shall perform operations on protected actions and data. In order to prevent misuse of the subjects rights in the object, the subject can limit the rights given to the object.
Each role contains zero or more capabilities. Roles and capabilities can be enabled or disabled. At any time, only a subset of the set of active roles and capabilites are enabled. In order to execute a protected action or to access a protected data structure, one of the enabled roles must contain the capability associated with that particular action. Moreover, this capability must be enabled.
Objects create the capabilities they need any time they like, and connect them to their actions and data structures. A user enable or disable certain roles to extend or limit her access rights. Roles and capabilities govern the authorization part of access control.
The identity of the application and the user together constitute a caller
profile which gets stored in the access control service. Reference to this
caller profile is given by access control handle. This handle is passed down from the business application (where it is initialized when the business application registers) with each invocation of an action of another service. The access control service maintains the association of access
control handles with the corresponding caller profile, its active roles, which
of those are enabled, and which capabilities belong to each role. Access
control handles govern the authentication part of access control.
Because the rights of an application change dynamically (roles may get
enabled/disabled, and capabilities can get added or removed from roles), the roles
and capabilities of one business application should be separated from the roles and capabilities of another.
If a role gets disabled for a particular application, that should not
implicitly disable the same role for all other applications. Roles and capabilities will therefore be marked with the id of either the user or the application owning a role or capability. For capabilities its is possible to create global capabilities with no mark associated.
Applications are implemented by JAVA classes. Only classes that
implement the
ControlledApplication
interface can register with the access control service as Business Applications. Exactly one controlling class in each Business Application distribution has to register as a controlled Application.
The ControlledApplication interface allows the access control service to retrieve the application profile through the properties associated with the Controlled Application in a distribution, and to transfer the constructed access control handle to the Controlled Application in a secure manner (using
storeAccessControlHandle()
).
To register an application, the controlling class is passed to
registerSignedApplication()
.
The registration process will read the properties for the class, created during installation, from the Archieve and return the application customized with its properties as an instance of the class
ControlledApplication. Calling its
main()
method will start the application.
All JAVA classes wishing to act as Module must be a subsclass of the
ControlledModule
to be able to register with the access control service as a module. Exactly one controlling class in each module distribution has to register. The ControlledModule class allows the access control service to retrieve the application profile
through the properties associated with the Controlled Module in a distribution, and to transfer the constructed access control handle to the Controlled Module in a secure manner using
storeAccessControlHandle()
.
To register a module, the controlling class is passed to
registerSignedModule()
. An instance of the class
ControlledModule. is created. This instance of the module will actually never run, but will deliver an access control handle to later loads of the module.
When the module is called (as an object with respect to access control terms) it will have the subjects access control handle passed and it will be able to get its own handle calling
getAccessControlHandle()
.
All capability types are subclasses of the abstract class
Capability
To guard access to data, the capability necessary to
retrieve it can be stored together with the data. When the data is later
retrieved, validity of that capability can be checked as described above .
All role types are subclasses of the abstract class
Role
The current role can be retrieved calling ach.popCurrentRole(role) and a new current role created using ach.pushCurrentRole(role)
A new empty access control handle is created with new AccessControlHandle(master_ach). The new handle is populated with ach.addRole(Role). If only the name of the role is known, the role object can be retrived with ach.getRole(role_name). or ach.getRoleNames(). This requires an ach with the role object as member is available.
For emergency stop the operations ach.freeze(), ach.wakeup() and ach.isFrozen() are available.
Register a Module like:
Module registration would normally happen from Library.init or the Installation module but the registration can be made from anywhere at any time.
Objects create the capabilities they need, and insert them in the appropriate roles, as in the following example.
Then, the object can protect its actions by guarding them with an if-statement
whose guard checks whether the corresponding capability is valid. For this
check the service calls hasRight() on the
access control handle of the subject, with the capability needed to perform the
action as parameter.
It should be noted that the capability object is needed to add a capability to a role, while only its name is needed to check it in an access control handle.
Object have normally two handles: Its own and the handle passed from the subject. It is not mandatory for the object to have a handle if it's not accessing protected resources besides its own resources.
Object can run as static or instantiated classes. The example below show parts of the code where a business application call an instantiated module class.
The business application
The module. One method where it act as object for access control,
and a second method where it acts as subject for access control. The
business application can choose to limit the rights in the access control
handle before passing it to the module (m1.action1()).
The short examples above gives hopefully a feeling of the possibilities in the ACM. Full blown examples will be available in the Test directory.
Overview of the Access Control Service
The Access Control policy imposed on Business Applications and Modules are different.
Business Applications <-> Business Applications
Business Applications -> Modules
Module <-> Module.
Business Applications
Access control in SEMPER is based on roles and capabilities.
Given the identity of the application and the user, an initial set of roles is
selected. These are called the active roles.
Modules
Modules use the same mechanism as the Business Application, but will have no user associated.
Authentication of Subjects
Business Applications
Subjects authenticate themselves to the access control service using the access
control handle. This handle uniquely describes the application and user ultimately responsible for accessing a resource.
Modules
The access control handle is constructed when the module register to the access control service, which normally will happen in library.init or during dynamic downnload/installing of a module.
Authorization of Subjects
SEMPER obejcts creates capabilities protecting resources
object for which access must be guarded. A subject is authorized and granted
access if and only if it owns a valid role containing the
valid capability. A capability is valid if it is enabled
and if it is a member of at least one enabled role owned by the caller.
Business Applications
If the required capability is only found in
disabled roles owned by the caller, the user is prompted to enabled each of these
roles in turn, until she enables one of them.
If the enabled role contains the capability, that capability is tested for validity.
Modules
Same procedure as for Business Applications
Capabilities
Persistent capabilities are created by SEMPER objects when needed and will survive the SEMPER session, while non-persistent capabilities only exist as long as the SEMPER service exist. Capability objects contains and are referenced on unique name and a unique description (used in interactions with the user).
Capabilities are members of one or more roles and are either enabled or disabled.
If a capability c is owned as object it can be added to a role r using
c.addToRole(r) and removed using c.removeFromRole(r). It can also be added to the speciel current role using
c.addToCurrentRole(r)
.
Other types of capability classes are easily added to the system and they can be mixed. An example: A mixed TimeOutCapability and PasswordCapability can give the opportunity to have password associated with TimeOut instead of a simple confirmation, and so on.
Standard SEMPER Capabilities
The access control service creates the one non persistent standard SEMPER capability on initialisation:
Roles
Persistent roles are created by SEMPER objects when needed and will survive the SEMPER session, while non-persistent roles only exist as lomg as the SEMPER service exist.Role objects contains and are referenced on unique name and a unique description (used in interactions with the user).
Roles own zero or more capabilities and are members of one or more access control handles. They are either enabled or disabled.
Other types of roles are easily added to the system and mixed like with capabilities.
Standard SEMPER Roles
The access control service creates the following two non persistent standard SEMPER roles on initialisation:
Using the Access Control Service
A capability is checked for membership of an access control handle and validity using ach.hasRight(capa)
Business Application
Register a Business Application like:
ControlledApplication ca =
AccessMan.registerSignedApplication
("name_of_controlling_class_for_business_application");
ca.main() ; // call the business application
Application registration would normally happen from applications menu, but the registration can be made from anywhere at any time.
Modules
AccessMan.registerSignedModule
("name_of_controlling_class_for_business_applicatio") ;
pwc = new PassWordCapability
("my_capa", "Testing", "test" ) ;
pwc.addToRole(subject_ach.getLoginRole()) ;
if (subject_ach.hasRight("my_capa"))
perform action ;
else
reject action ;
public class LoadedApplication implements ControlledApplication {
private static AccessControlHandle __my_ach = null ;
private static boolean __called_before = false ;
// other interface methods
public void storeAccessControlHandle(AccessControlHandle ach)
{
// called when business application registers, check that
// it is only called once.
if (!__called_before) {
__called_before = true;
__my_ach = ach ;
}
}
public void main()
{
// LoadedModule is instantiated and called
LoadedModule m1 = new LoadedModule(__my_ach) ;
// do something in m1, that requires a right in the handle
m1.action1() ;
}
}
public class LoadedModule extends ControlledModule {
// my own handle
private AccessControlHandle _my_handle = null;
// subjects handle
private AccessControlHandle _handle = null;
// Constructor, called from the application creating
// the new module instance
public LoadedModule(AccessControlHandle subject_handle) {
this._handle = subject_handle ;
}
public void action1() {
// I act as object.
if (this._handle.hasRight("my_capa"))
perform action ;
else
reject action ;
}
public void action2() {
// I act as subject
this._my_handle = getAccessControlHandle();
// ms.actionx is a method in a static module class
// I act as my self
ms.actionx(this._my_handle) ;
// or I act as the subject from action1
ms.actionx(this._handle) ;
}
}