[A version of this paper appeared in the 1998 USENIX COOTS conference]
SDM is a Secure Delegation Model for Java-based distributed object environments. SDM extends current Java security features to support secure remote method invocations that may involve chains of delegated calls across distributed objects. The framework supports a control API for application developers to specify mechanisms and security policies surrounding simple or cascaded delegation. Delegation may also be disabled and optionally revoked. These policies may be controlled explicitly in application code, or implicitly via administrative tools.
Open distributed computing environments must address four symmetrical security issues:
This paper describes the delegation-based mechanisms that underly a proposed framework, the Secure Delegation Model. SDM integrates support for these different aspects of security in Java-based distributed systems.
SDM is an architectural framework for structuring remote method invocations (RMI) among distributed components. It does not involve new encryption techniques, authentication protocols, or language constructs. SDM instead builds upon existing mechanisms, mainly those already established in the Java JDK1.2 security framework, to establish a practical basis for constructing flexible yet secure components and support infrastructure.
This paper focuses on the way in which delegation is structured and used in SDM to support secure operation when multiple components together provide a given service. Other aspects of the framework are described only briefly. Readers may find further details in [7].
The remainder of this paper is structured as follows. Section 2 defines Java-based security concepts and terminology surrounding Principals, Permissions, Privileges, Roles, and Security Domains. Section 3 introduces the SDM delegation framework. Section 4 describes the details of the resulting protocols, which are extended in Section 5 to handle dynamic revocation of delegated privileges. Section 6 briefly compares SDM to other approaches.
role: President-of-USA
capability: OccupyWhiteHouse
group: AmericanPresidents
accessId: WilliamClinton
Note that the permission to occupy the White House may be a capability transiently issued to him, with an expiration at the end of his presidency.
A principal A may adopt role R and act with the identity (A as R) when transiently obtaining or reducing powers. The privileges associated with a role work in the same way as those associated with principals. For example, a Manager role might have privileges:
group: CEOAnnouncementRecipients
group: companyBudgetReviewers
capability: MakeAppointmentOffer
-grantedBy Company
capability: ChargeCompanyCreditCard
-grantedBy Company
A principal plays a role by associating itself with one of its roles for a particular period of time. Thus, these privilege attributes must become associated with the principal. In SDM, this is accomplished by querying the RoleIdentity for its privileges.
To support PrincipalDomains, the Java runtime system must maintain a mapping from <CodeSource, CodeExecutor> pair to their protection domains and also the mapping between protection domains and their privileges. This could, for example, be implemented at the execution stack level with the aid of class blocks and the executing environment frame, as illustrated in Figure2. More complete details can be found in [7,6].
Secure delegation occurs when one object (the delegator or initiator) authorizes another object (the delegate) to perform some task using (some of) the rights of the delegator. The authorization lasts until some target object (endpoint) provides the service. The essence of secure delegation is to be able to verify that an object that claims to be acting on another's behalf, is indeed authorized to act on its behalf[15].
The problem becomes more complicated in practice when we consider mobile objects, agents and downloadable content being passed around an open network, where the initiator need not have a clue of where all its representative objects are passed around. Additionally, a number of practical issues must be solved: the framework must be scalable in wide area networks, remain efficient under widespread use, and remain secure when dealing with complex trust relationships that can emerge in practice. Toward these ends, SDM provides a multifaceted approach, supporting any of several styles and protocols, including both simple (impersonation) and cascaded (chained) delegation, as well as means to disable and revoke delegation.
In Java (as of release 1.2), a protection domain is created for each CodeSource. In SDM, this notion is extended to form PrincipalDomains based on CodeExecutors as well. A target (or intermediate) controls access to its methods based on protection domains, i.e., <PrincipalDomain, ProtectionDomain> pair. Access is then controlled via the permission associated with both the CodeExecutor and/or CodeSource.
SDM delegation protocols are based on the notion that when a client delegates its rights to one object in a domain (i.e., when it enables delegation before invoking on a target object), it effectively delegates its rights to all the objects in that domain. This is implemented via DelegationCertificates , that behave analogously to RoleCertificates. In particular, a DelegationCertificate passed to a delegate can only be used by the object it is issued for.
A set of security requirements is associated with each object. If an intermediate object needs delegation from an initiator, it specifies the delegation mode in its security requirements. Depending on the context (see Section 4), a delegation session may be established. If the target does not need to further delegate actions, no delegation certificate is generated by the client.
When initiating a delegation session, information about the initiating principal (CodeExecutor) is associated with the context of invocation. This is propagated through the underlying layer to the remote server (target) and is associated (principal and CodeSource pair) with a protection domain. The target may provide access based on the identity of an individual or based on privileges it has (based on its effective role during invocation).
A series of objects may be involved in a given service request. For example, suppose some object A (client) invokes a method on another object B (target). Object B might complete the task on its own or might in turn invoke a method on another object, C. In this context, object B which was earlier the target (for A's invocation) becomes a client for the method invocation on object C. Thus objects that are at first targets may later become clients. This effectively forms a delegation chain where object A is the initiator , object C is the final target and object B is an intermediate .
There are three different approaches, or modes , that may apply to such chains (see Figure 3):
After obtaining the delegation certificate from a delegator, an intermediate object might invoke a method on another object down the chain. At this point, the intermediate may decide to use only the delegator's privileges or combine it with its own privileges. This decision of either passing delegator's privileges only (impersonation) or combining its privileges too (composite) is based on the delegation mode specified for the intermediate object. Mode specification may be explicit through the application, or may be implicitly set by the administrator of that object service.
Objects can explicitly enable delegation at the application level. This is accomplished by using an AccessController object. The AccessController method enablePrivileged() permits delegation. Method enablePrivileged(RoleType) is similar, except that when a role type is passed, the available privileges for that session are extended or restricted to the privileges associated with that enabled role. This functionality is not restricted to delegation. It can also be used whenever access to local methods and resources need special control. For example, consider a system administrator who logged in as a normal user but would like to exercise super-user privileges for an account creation. In this case, the method (which has autheniticated the user to have super user privileges) would invoke enablePrivileged(superUser) to enable super user privileges, as illustrated in Figure 4.
Either implicit or explicit enabling can be used to specify control in cases of Cascaded Delegation where the intermediary objects are unaware of secure delegation. If the intermediate is unaware, then the underlying security layer must effectively carry out either Simple Delegation or a special delegation mode set by an administrator. In SDM, explicitly specified modes are settable at the application level and may override the default mode set by the administrator. Either way, delegation requirements become attached to an intermediate object's reference. This set of requirements is made available to any client holding a reference to this remote (intermediate object) reference.
In contrast, a delegation-aware intermediate might explicitly enable delegation for a method call. In SDM, this explicit delegation may be performed at the application level. If delegation is enabled, the client may generate a delegation certificate and pass it on to the intermediate object. Otherwise, no delegation certificate is generated and the intermediate provides service using only its privileges and none of the delegator's (in which case, NoDelegation is the delegation mode).
An intermediate may also explicitly enable delegation using the AccessController methods enableSimpleDelegation() and enableCascadedDelegation(). The specified delegation mode is taken into account when privileges of the intermediate need to be presented to consecutive objects in the method invocation chain. Whether the intermediate's privileges are combined with the delegator's is based on the mode of delegation. The system can obtain the security requirements attached to any remote reference. The delegation, if required by the specified requirements (and target object is thus willing to act as a delegate), is activated appropriately from the context. Using the context of invocation, a delegator's AccessController determines the CodeExecutor who is executing the client's code. This CodeExecutor becomes the Signer of a delegation certificate, and thus, effectively, the initiator of a delegation.
An example of application-level control is shown in the code segment in Figure 6. This code could be used to handle situations in which a client object invokes method obtainInsuranceInfo() on a servlet object, InsuranceDBServlet. The InsuranceDBServlet object might in turn invoke methods on a some enterprise service in the insurance company, say, an insuranceServer object. In the sample code, the InsuranceDBServlet explicitly enables delegation before further invocation on insuranceServer.
When an object decides to delegate a task to another object (effectively to the CodeExecutor of that object), it creates a delegation certificate. This certificate specifies the initiator, role it is delegating, any constraints that are bound to the delegation, a nonce, validity period and its DelegationServer name for handling queries regarding delegation revocation. A role certificate is associated with the role being delegated, which might contain a set of privileges associated with it.
A delegation certificate is generated using the CodeExecutor as the FromPrincipal and the CodeExecutor of the remoteAdmin object as the ToPrincipal. Implementations could be based on public key cryptography using X.509 certificates, as illustrated in Figure 5. The associated role (and hence, set of privileges) is specified in the certificate.
A delegation certificate is issued for every delegation session unless an earlier delegation has been set to remain valid for consecutive sessions. The type of the delegation certificate (SimpleDelegationCert or CascadedDelegationCert) reflects the kind of delegation that is activated for this session. If the delegation is revocable, the endpoint makes sure that the delegation certificate is not revoked before it provides access.
Selection of consecutive delegates is made by an intermediate. The selected principal (CodeExecutor of the selected object for further delegation) is verified to be a permitted delegate by invoking the isPermittedDelegate(Principal) method on the certificate (DelegationCertificates must implement the Delegation interface shown in Figure 5). This method will scan through the list of exempted delegates (if any) and accordingly will return a boolean value, indicating whether or not the principal is a valid delegate.
SDM employs a set of basic protocols that underly the usages described in Section 3. SDM delegation protocols specify what information gets exchanged when an object A invokes a method on object B. The underlying layer must determine the delegation mode to be enabled from the context and security requirements attached to the target (remote reference B). Thus, the security policy for an intermediate object governs which privileges and delegation mode to apply at any given context. (See Figure 7.)
Different rules apply for each of the combinations of required and specified modes that can occur in a sequence of invocations from object A to object B to C. (i.e A B C):
Once the intermediate B has obtained the delegation certificate DCab from A, it has the authority to speak for A. To complete the service, B might have to invoke methods on other objects. When B selects C to be the next target, B represents an entity (B for A) and requires access to method invocation. At this point B exercises the type DelegateIdentity and during the process of becoming a DelegateIdentity, the delegation mode is considered to calculate the privileges of the delegate (here, B). In this case of B being a DelegateIdentity, B can authenticate for itself. Also, it provides the delegation certificate DCab to prove that A has indeed delegated the task to B. C authenticates that it is actually B it is talking to, through normal authentication procedures. It verifies the delegation certificate to be signed by A by verifying the digital signature of A that is engraved in the certificate DCab. These provide proof of the fact that ``B speaks for A'', abbreviated as or (B for A)[1]. The delegate's (B's) getPrivileges() method returns the privileges associated with B, which is either only the privileges gained through delegation (A's privileges only), or also includes the privileges of the delegate identity itself (both B's privileges and A's privileges). Thus the set of privileges returned by the delegate reflects the privilege of the identity (B for A) during that context.
Based on access control policies on the target C, the method invocation and any related resource accesses are controlled. These access control policies may be based on only the initiator (A) or might depend on the delegates as well.
If C requires delegation from its requester and B is a delegate for A possessing a delegate certificate DCab, i.e., (B for A) then:
In contrast, if B is not a delegate for A, that is if B had not specified delegation in its security requirements, then A would not have generated (and passed on) the delegation certificate DCab to B. In this case, when a request is issued to C, it is not possible for B to establish A as the original initiator due to the lack of a delegation certificate. So C must treat it as if the request originated from B and handle it accordingly, without having any idea about the involvement of A in the complete invocation chain. Extending this chain to one more principal, we get A B C D. If B does not require delegation and C does, then when the request reaches D, D will treat the request to have initiated from B and delegated through C.
Thus, at any given time, control is based only on currently available information on the delegation chain and the specified modes and policies. SDM does not support any means of tracing back calls through intermediaries to obtain predecessor delegation certificates.
Consider an example of an requestor (insurance agent) using the services of a InsuranceDBServlet object to obtain Insurance information for a customer. This is illustrated in Figure 6. Let a servlet object provide services related to insurance information for a company, using other enterprise services. It might in turn need to make use of the services of InsuranceServer. The requestor obtains the reference of the servlet and invokes the obtainInsuranceInfo method on it by passing the id of the customer for whom the information is obtained. The servlet might specify, attached with its object reference, a set of security requirements. Let the security requirements specify that Delegation is required. In SDM, our system will analyse this security requirement attached to an intermediate object (in this case, the servlet) and whether the requestor is willing to delegate (known from requestor's security specification attached to its object reference). The underlying system generates a delegation certificate and passes it on to the servlet.
Let the servlet contact the InsuranceServer object to obtain the insurance information by invoking the getInsuranceInfo method. (we assume that the servlet has already authenticated and established connection with the InsuranceServer). The servlet provides the delegation certificate issued by the requestor. The InsuranceDBServlet object acts as a delegate, acting on behalf of the requestor (impersonating the requestor), and makes a request to the InsuranceServer. For this request, the servlet uses the privileges of the intiator (as the insurance server might make use of requestor's privilege of being a insurance agent). Thus the servlet makes use of the SimpleDelegation facility provided by SDM while invoking the getInsuranceInfo method on the InsuranceServer object.
Sometimes users and services need to revoke privilege assignments. Users change their minds; people leave groups, services change functionality, and so on. Even though it adds complexity, any practical delegation protocol must support revocation.
In SDM, revocability is an optional attribute of delegation. If performance is an issue, or revocation is somehow known to never be necessary, the delegation can be made non-revocable. This facility to explicitly enable or disable revocation is again carried out using the AccessController object. The changed revocation status remains valid, until it is changed again. The AccessController method setRevocableDelegation(true) enables delegation to be revocable until it is set otherwise.
If delegation is revocable, then the endpoint (but not necessarily any of the intermediate delegates) of a chain must be able to find out. In SDM, the DelegationID and delegation server (URL) associated with certificates define the uniqueness of a delegation certificate. If the endpoint has not seen the delegation certificate earlier, it must contact the DelegationServer of the initiator and verify its validity. And if it is not a one-shot delegation (a delegation that is valid for one access request only), the endpoint registers itself as a DelegationRevocationListener with the initiator.
When an endpoint receives a service request from a principal, its AccessController checks if the service has been delegated through the invoking principal, and if so whether the delegation is revocable. If the delegation is not revocable, it goes ahead to provide/deny access according to the delegates privileges.
But if the delegation is revocable:
In SDM, revocation is possible even when the initiator does not know the endpoint a-priori. When an endpoint (final target) receives a revocable delegation request, it registers with the initiator as being interested in receiving revocation notifications. Thus each of such endpoints register themselves as DelegationStatusListeners to the initiator. The initiator in turn maintains a list of endpoints to whom its delegation has propagated. These endpoints will implement the NotificationHandler interface, to handle any event notification.
If the endpoint contacts the initiator every time before servicing a delegated request, then the endpoint is considered to follow a pure pull mechanism to obtain the status information from the initiator. A common alternative is pure push mechanisms, in which the initiator continually broadcasts out revocation information. Analyses of similar protocols using Broadcast Disks [3] show that pure pull provides extremely fast response time for a lightly loaded server, but as the server becomes loaded, its performance degrades, until it ultimately stabilizes. The performance of pure push is independent of the number of clients listening to the broadcast. But if the number of interested clients (endpoints) is large, then its a waste of resources to send irrelevant data. A more serious problem is that the servers might not deliver the specific data needed by clients in a timely fashion. One solution suggested by Zdonik [3], is to allow the clients to provide a profile of their interests to the servers.
In SDM, the clients are the endpoints who are interested in the revocation status of certain delegations (serviced by those endpoints). When an endpoint receives a delegated request, the first time around it pulls information from the initiator about revocation status and at the same time registers itself to receive delegation-related events. The profiles of those endpoints of interest in SDM, are the details on whether they require periodic push or aperiodic push. A aperiodic push is event driven - a data transmission is triggered by an event such as data update (in SDM, it is a change delegation status). As a result, endpoints (and hence, the NotificationHandlers) are notified of any change in delegation or its privileges by the initiator (which might use a helper object that implements EventGenerator interface). A periodic push is performed according to some pre-arranged schedule. The endpoint, when it registers itself with the initiator, will specify the time interval of periodic updates (pushes). Hence, the initiator will push delegation details at specified time intervals to the registered endpoints. This leaves it to the endpoint to specify whether it needs aperiodic or periodic (if so, the necessary time interval) pushes. Thus the endpoint need not pull information after its initial ``pull'' as the initiator will ``push'' (revocation) data to registered listeners (endpoints). Either periodic or aperiodic, this pull-once-push-many approach supports revocation where an endpoint receives revocation notifications from an initiator.
An endpoint will decide to specify its interest in periodic or aperiodic pushes from the initiator based on how critical the revocation affects its service and its resources. For example, if the endpoint is a TelephoneDirectory service then providing information to a requesting delegate (a secretary object) about a revoked number is not very crucial, as the delegate might not misuse the telephone number. In this case, periodic pushes from the service department is not necessary and the endpoint might settle in for aperiodic pushes only. On the other hand, if the requested service is providing classified information, then the endpoint needs to know the revocation of the delegate (for example, a secretary object) immediately. In this case, short-interval periodic pushes from the service department may be selected. The load on the server to keep pushing revocation status of its delegates becomes worth its cost when compared to the risk involved in providing classified information to any revoked delegate.
This paper has focussed on the way in which delegation is structured and used in SDM to support secure operation when multiple components together provide a given service. SDM builds upon exisitng mechanisms, mainly those already established in the Java JDK1.2 security framework, to establish a practical basis for constructing flexible yet secure components and support infrastruture. SDM extends the JDK1.2 framework to include explicit support for principals. We have provided an implementation strategy for SDM to be built over the JDK1.2 framework.
As outlined in section 2.2, implementation of SDM requires that the JDK1.2 domain model be extended to include principals, so that each CodeSource will also have a principal associated with it. One domain will be formed for each such <CodeExecutor, CodeSource>. Further authentication and access control (and delegation) may then be based on the CodeExecutor.
To support PrincipalDomains, the Java runtime system must maintain a mapping from <CodeSource, CodeExecutor> pair to their protection domains and also the mapping between protection domains and their privileges. This could, for example, be implemented at the execution stack level with the aid of class blocks and the executing environment frame, as illustrated in Figure2.
In the future, we intend to implement our SDM delegation framework over the JDK1.2 security framework. We have already implemented access control mechanisms [17] based on CodeSource information. We plan to extend the mechanism to include the information on principals to further control any access requests.
SDM provides a realistic security framework for Java-based distributed object systems. It isolates the complexities of the underlying protocols necessary to provide a very wide range of security policies and trust levels. It presents application writers and system administrators with a flexible, uniform API. SDM appears to be the most conservative extension of the Java 1.2 security architecture that simultaneously supports both delegation- and role-based security, along with revocation mechanisms that are often needed in practice.
The design of SDM has also benefited from other work in security architectures, but differs from previous systems in significant ways:
We are aware of the following limitations of SDM, that reflect some of engineering trade-offs encountered in its design:
This document was generated using the LaTeX2HTML translator Version 97.1 (release) (July 13th, 1997)
Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
The command line arguments were:
latex2html -split 0 delegation.tex.
The translation was initiated by Doug Lea on 12/15/1998