Title: FW: [schema] Translating Java Policy API to SAML/XACML ---------- From: Anne Anderson[SMTP:
Anne.Anderson@Sun.com] Sent: Tuesday, April 09, 2002 3:25 PM To:
Carlisle.Adams@Entrust.com Subject: [schema] Translating Java Policy API to SAML/XACML [Carlisle, please forward this to the XACML mailing list. My e-mail address has not yet been repaired. Thanks. -aha] ** This proposal is still under review by Sun's Java developers, ** so it should be considered a very rough draft. There is no ** implied commitment on the part of Sun to implement any of this. Title: Translating Information from the Java Policy API into SAML/XACML Author: Anne Anderson Version: 1.4, 02/04/09 The Java Policy mechanism could interoperate with XACML in one of two ways: 1) The information in the Java Policy API could be translated into SAML and passed to an XACML PDP, 2) The XACML policy could be translated into objects that could be used by a Java Policy provider directly against the information in the API. Since the XACML TC scope is to handle requests in SAML syntax, I am going to describe the first approach. I believe this illustrates most of the issues that will arise in taking the second approach as well, since it exposes the types of information that need to be referenced from an XACML policy for Java. Later, I hope to describe the second approach. 1. Java Policy API Information While there are several methods in the Java Policy API, the critical one for interoperability with XACML is "implies": public boolean implies(ProtectionDomain domain, Permission requestedPermission) The next two sections describe the components of this API. More information about the Java Policy API and its component classes is available in
http://lists.oasis-open.org/archives/xacml/200201/msg00082.html Skip to Sections 2 and 3 if you are already familiar with the Java Policy API. 1.1 Java ProtectionDomain A "ProtectionDomain" is an object that can encapsulate five types of information: - CodeSource: - URL: the URL from which the Classes associated with this ProtectionDomain were loaded. - Certificate[] containing certificates used to verify the signature on the Classes associated with this ProtectionDomain. - PermissionCollection: a collection of Permission objects, representing Permissions for which Classes associated with this ProtectionDomain have static rights. These are granted by the ClassLoader. The ClassLoader MAY get these Permissions from the Policy.getPermissions() API, but not necessarily. - ClassLoader: a reference to the ClassLoader used to load the Classes associated with this ProtectionDomain. - Principal[]: an array of names of the entity associated with the executing code (i.e. the Subject). If the entity authenticated under multiple names, this array can contain an entry for each name. There is a ProtectionDomain associated with each frame on a thread stack. Access is granted only if ALL ProtectionDomains (or all down to a PD marked as Privileged) return TRUE from the Policy.implies call OR from a ProtectionDomain.PermissionCollection.implies call using the statically granted permissions. I am assuming that this iteration can be performed by a front-end to the XACML PDP, so each saml:AuthorizationDecisionQuery need express only one such Policy.implies call. 1.2 Java Permission A "Permission" is an object encapsulating a description of the operation for which access is requested. It is also used to describe accesses that are permitted. A Permission has a String "name", usually representing the the requested target resource or task, and an optional String "actions". Permission objects are subclassed for particular types of resources. Some examples of such subclasses are: - FilePermission (access files) - SecurityPermission (set the Policy object, create an access control context, install provider objects, ...) - PrivateCredentialPermission (access private credentials associated with a Subject) - DelegationPermission (use Kerberos forwardable and proxiable tickets) - LoggingPermission (control logging configuration) - SQLPermission (set the logging stream for SQL) - SSLPermission (access or modify the SSL session information) - AudioPermission (access and control audio devices) - AuthPermission (run as "privileged" code, get the Subject associated with the current thread, modify set of Principal names associated with a Subject, ...) - SocketPermission (access sockets), - PropertyPermission (read or write system properties) - AWTPermission (control and access graphical display, such as accessing the event queue, accessing the clipboard, reading pixels, ...), - RuntimePermission (create a ClassLoader, set the SecurityManager, exit from the JVM, ...) The important Permission method is "implies": public boolean implies(Permission otherPermission) This method returns TRUE only if the "otherPermission" is a subset, or is "covered by", this Permission. What it means to "imply" another Permission is completely under the control of the specific Permission subclass. It can make use of the Permission information in any way it is programmed to do. Specifically, there is no requirement that either "name" or "actions" be of a particular form. "actions" can only be parsed by the Permission subclass that handles them. A wrinkle is that a Permissions that are granted can span more than one Permission object. For example, one FilePermission can grant "read" access, while another FilePermission can grant "write" access. If the user requests "read, write" access, then both FilePermissions must be logically "merged" to determine that this access is allowed. In the case of FilePermission, the separate actions are comma-separated strings, but this is not the case in general. One Permission could grant part of a complex access action, and another Permission could grant an overlapping part of a complex access action. Only the Permission subclass itself could tell if the two actions together "match" a request to perform the entire complex action. Normally, a Permission is only compared to other Permissions that are of the same subclass. But there is a mechanism for a Permission to associate itself with Permissions of another sub-class. To handle both the above cases, each Permission object implements a "newPermissionCollection" method. This returns null unless one of the two cases above applies. If it does not return null, the method returns an empty instance of the PermissionCollection with which instantiations of this Permission subclass must be merged. If all Permission objects are stored in their corresponding PermissionCollection, then "PermissionCollection.implies(requestedPermission)" will handle any necessary merging of targets and actions to produce the definitive result. 2. SAML Translation Issues The following is based on SAML draft-sstc-core-29. The Version 29 AuthorizationDecisionQuery has a single Subject element with an anyURI-type attribute of Resource. It consists of: - a single NameIdentifier String-type element with optional NameQualifier and Format attributes, - 0 or more Action anyURI-type elements with a Namespace attribute. 2.1 Subject SAML says the <Subject> element specifies the principal that is the subject of the statement... A <Subject> element SHOULD NOT identify more than one principal. The Java Policy API, however, can present multiple principals of three types: - The principal associated with the execution of a thread stack stack that makes an access request. This is often the "user" who is executing the application thread. This principal may have multiple names if the principal authenticated under more than one name. Java uses the Principal class such that various attributes of the "user" are expressed as Principal objects of specific subclasses. - The principals who signed the code that is executing. These are represented by their public key certificates in the Java Policy API. Each public key certificate may contain multiple names for the subject principal: the Subject Distinguished Name and the Subject Alternative Name Extensions. - The principal representing the location from which the code was loaded. This is expressed as a single URI in the Java Policy API. Proposal: 1. Extend <saml:Subject> to allow multiple <saml:NameIdentifier> elements. The NameQualifier attribute can be used with each <saml:NameIdentifier> to distinguish the Java Principal sub-class and/or type (DN, OID, IP address, RFC822Name, etc.) This will allow a single Subject to express multiple names for the same principal. 2. Extend <saml:AuthorizationDecisionQuery> to allow multiple <saml:Subject> elements. Extend <saml:Subject> to have a NameType attribute by which Executing Principal, CodeSource Signer, and CodeSource URL subjects may be distinguished, and a NameSpace attribute by which these special J2SE names can be identified. An alternative for dealing with CodeSource URL would be to extend the <saml:AuthorizationDecisionQuery> to include zero or more <saml:Attribute>s. This would not work so well for the other principal types because they can each have multiple names that need to be kept in association. 2.5 Requested Permission The requested Permission encapsulates not only the Resource and the Actions, but also the matching algorithm for comparing the attribute values of this Permission to the attribute values that may be expressed in the XACML policy. A target Resource and Actions can be extracted from the Requested Permission object in the Java Policy API, but we then lose the information about the Permission subclass, which is essential for understanding what the Resource and Actions mean and how they match. Once we agree that we need more than one <saml:Subject> in a <saml:AuthorizationDecisionQuery>, it seems that Resource should not be an XML attribute of the <saml:Subject>, and Action should not be an element of the <saml:Subject>. Both should be in one or more separate elements. To provide this information, I propose use of a new <saml:Resource> element with two attributes: Namespace and ResourceType. The Resource type has two sub-elements: ResourceName and ResourceAction. The entire string returned from requestedPermission.getActions() is placed into a single "ResourceAction" element, since there is no reliable way to parse it into separate actions. 2.6 Static Permissions The PermissionCollection in a ProtectionDomain must be evaluated together with whatever policy specification is used by the Java Policy implementation, since the general case requires that Permissions be logically merged. For example, the executing user may be requesting to "read" and "write" a given file, but "read" access is granted in the static PermissionCollection and "write" access is granted in the XACML Policy. Evaluated separately, each would return DENY to a request asking for "read and write" access. The static Permissions could be passed as a serialized object in a SAML Attribute if the <saml:AuthorizationDecisionQuery> is expanded to include <saml:Attribute>s. I suggest the following: Let "hexBytes" be the Base-64-encoded value of the serialized PermissionCollection object. <saml:Attribute AttributeName="java.security.PermissionCollection" AttributeNameSpace="j2se"> <saml:AttributeValue> "hexBytes" </AttributeValue> </Attribute> 2.7 ClassLoader The ClassLoader specified in the Java Policy API could be expressed in a saml:Attribute if the saml:AuthorizationDecisionQuery is expanded to include <Attribute>s. 2.8 Full Query Example Example: The following AuthorizationDecisionQuery represents a Java Policy API invocation where: - The user Subject associated with the executing stack authenticated using an X500 Distinguished Name via a smart card login module. - The code pointer in the stack frame is within a class loaded from " file:/netjavaxjdk1.4/classes ". - The class code was signed by two certificates, one of which had an X500 Distinguished Name, and the other of which had an RFC822 name and a CertificatePolicyExtension value. - Read and write access is requested to the directory /home/aha/personal/. - Some set of static Permissions was passed to the Java Policy.implies API. <saml:AuthorizationDecisionQuery> <saml:Subject Namespace="j2se" SubjectType="ExecutingPrincipal"> <saml:NameIdentifier NameQualifier="javax.security.auth.X500Principal"> "cn=Anne, ou=SunLabs, o=sun, c=us" </NameIdentifier> <saml:NameIdentifier NameQualifier="com.sun.labs.LoginTypePrincipal"> "SCLoginModule" </NameIdentifier> </Subject> <saml:Subject Namespace="j2se" SubjectType="CodeSigner"> <saml:NameIdentifier NameQualifier="javax.security.auth.X500Principal"> "ou=JavaSoft, o=Sun, c=us" </NameIdentifier> </Subject <saml:Subject Namespace="j2se" SubjectType="CodeSigner"> <saml:NameIdentifier NameQualifier="javax.security.auth.X500Principal"> "RFC822:
sunlabs@East.sun.com" </NameIdentifier> <saml:NameIdentifier NameQualifier="sun.security.x509.CertificatePolicyExtension"> "0.2.4.12.5.126" </NameIdentifier> </Subject <saml:Attribute AttributeName="CodeSourceURL" AttributeNameSpace="j2se"> <saml:AttributeValue> " file:/net/javax/jdk1.4/classes " </AttributeValue> </Attribute> <saml:Attribute AttributeName="ClassLoader" AttributeNameSpace="j2se"> <saml:AttributeValue> "com.sun.east.sunlabs.XClassLoader" </AttributeValue> </Attribute> <saml:Attribute AttributeName="java.security.PermissionCollection" AttributeNameSpace="j2se"> <saml:AttributeValue> "hexBytes" </AttributeValue> </Attribute> <saml:Resource Namespace="j2se" ResourceType="java.io.FilePermission"> <saml:ResourceName> "/home/aha/personal/*" </ResourceName> <saml:ResourceAction> "read, write" </ResourceAction> </Resource> </AuthorizationDecisionQuery> 3. XACML Policy Evaluation Issues Assume we have a <saml:AuthorizationDecisionQuery> such as above. What are the types of issues that will come up in expressing policy against this type of query? 3.1 Multiple signing certificates Rules may require that a given CodeSource be signed by multiple specific principals, perhaps using certificates containing specific field or extension values. The CodeSource may actually be signed by many principals, of which these need to be a subset. This is a place where using a subset operation and being able to refer to an XPATH node set in the query from the XACML rule may be useful. Something like: <isSubsetOf> <valueRef> saml:Subject[@Namespace="j2se" @SubjectType="CodeSigner"]/ NameIdentifier[@NameQualifier="javax.security.auth.X500Principal"]/ </valueRef> <value> "ou=javasoft, o=sun, c=us" </value> </isSubsetOf> 3.2 Multiple Executing Principal Names The policy may require that the executing principal have authenticated under more than one name, or with specific credentials. The request may indicate that the principal has actually authenticated under even more names. The set of such names in the request, however, must be a subset of the names specified in the policy. This is another place where the subset operator with an XPATH node set would be useful. 3.3 rule Combiner Handling the "overlapping Permission" problem in Java requires some special processing. First, I propose to allow a <rule> that is in a XACML policy used for Java to return not only a list of missing attribute references, but also the required values of those missing attribute references. Second, I propose a special <ruleCombiner> algorithm for use with Java Policies that does the following: - constructs a Java Permission object from the information in the Resource Attribute of the the <saml:AuthorizationDecisionQuery>. - instantiates the java.security.PermissionCollection Attribute as the "overall" Java PermissionCollection. If there is no such Attribute, then construct an empty "overall" PermissionCollection [This attribute could then be removed from the <saml:AuthorizationDecisionQuery>.] - evaluates each <rule> using all information from the <saml:AuthorizationDecisionQuery>. If the <rule> returns PERMIT, then the <ruleCombiner> returns PERMIT. - re-evaluates the <rule>, omitting the input <Resource> element. If the <rule> returns ERROR with "insufficient information", and the only missing information are references to the <Resource> element, then - for every such reference in the <rule>, construct a new Permission object using the required <saml:Resource[ResourceType]> as the Permission class, the required <saml:Resource/ResourceName> as the Permission "name" value, and the required <saml:Resource/ResourceAction> as the Permission "actions" value. Call the "p.getPermissionCollection()" on this new Permission object. If it returns null, add the new Permission to the default PermissionCollection. Otherwise, add the new Permission to the specified PermissionCollection object and then add the object to the "overall" PermissionCollection. [The ruleCombiner MAY invoke overallPermissionCollection.implies(permissionFromResource) after each addition. If this invocation returns TRUE, then the <ruleCombiner> should return PERMIT, and the PDP should return PERMIT.] - After all <rule>s have been processed, invoke "overallPermissionCollection.implies(permissionFromResource)". If this returns TRUE, then the <ruleCombiner> returns PERMIT. Otherwise, the <ruleCombiner> returns DENY. -- Anne H. Anderson Email:
Anne.Anderson@Sun.COM Sun Microsystems Laboratories 1 Network Drive,UBUR02-311 Tel: 781/442-0928 Burlington, MA 01803-0902 USA Fax: 781/442-1692