Representing and Managing Authorization Policies

As we'll see in Chapter 18, policies play an important role in building an identity infrastructure, because they help define the context within which systems are built and operated. However, merely writing a policy does not ensure that it's correctly promulgated and implemented throughout the IT infrastructure.

For example, in the State of Utah, there are over 1,000 separate systems, not including desktop computers, that are affected by IT policies created by the CIO's office. What's more, several hundred people administer these systems. In this situation, there is little hope that any policy made will be consistently executed on these many disparate systems.

This problem plagues large enterprises. Access-control policies are written in English and then implemented on dozens or even hundreds of different systems individually. Each of these systems has a proprietary configuration language. Compounding the problem, policies change frequently. Every time the access control policy is changed, the entire configuration has to be redone. Only a hopeless optimist would believe that this job is done correctly.

Figure 11-7 shows how a policy server might solve this problem. In the figure, the policy is translated to some machine language and placed on the policy server where it can be sent directly to the various systems in the enterprise. As we discussed in Chapter 3, current state of the art in policy languages is a far cry from the ideal situation pictured here.

Using a policy server

Figure 11-7. Using a policy server


eXtensible Access Control Markup Language (XACML), is one standard that is addressing this problem. XACML is an XML-based language for storing and sharing access-control policies. XACML is a language for the policy decision point (PDP). As illustrated in Figure 11-7, the goal of XACML is that each PDP in the organization could use a single policy without constant manual configuration and reconfiguration. There are significant hurdles to achieving this result, including the variety of meanings that a single policy can have in various systems and contexts. As I mentioned at the beginning of this chapter, XACML is not widely accepted yet, and there are other, competing standards, but it serves as a good example of the type of language that will fill this need.

Whereas SAML provides a format for exchanging identity and access information, XACML provides a format for describing what to do with that information. There is some overlap between SAML and XACML: both provide a request/response language. The two standards are complimentary, however, using the same definitions for subjects and actions. But XACML goes beyond SAML in creating a rule-based language for expressing access-control policies.

Because XACML is at its core a programming language, it is much more complicated than the other standards that we've discussed, which are used for merely representing data. Policy rules can be created to allow fine-grained control over access. These rules can be based on items such as:

These can be combined using Boolean connectives to create complex policies (e.g., allow users from accounting to update this document only over HTTPS but allow users from other departments to read it anytime over HTTP). XACML also has a concept called a "combining algorithm," which allows multiple, perhaps conflicting, policies to be applied to a resource and some action taken as a result. For example, the combining algorithm might simply state "deny access if any policy denies" or it might be more complicated.

The following example is taken from "XACML: A New Standard Protects Content in Enterprise Data Exchange" on the Sun Developer web site.[*] The XACML request states that an unstated subject wants to log into a server called "SomeServer." The request has three primary parts: it identifies the subject making the request, names the resource, and describes the action.

    <Request>
      <Subject/>
      <Resource>
        <Attribute
          AttributeId="urn:oasis:...:resource-id">
          <AttributeValue>SomeServer</AttributeValue>
        </Attribute>
      </Resource>
      <Action>
        <Attribute AttributeId="ServerAction">
          <AttributeValue>login</AttributeValue>
        </Attribute>
      </Action>
    </Request>

This request would be processed using a policy statement that is expressed in XACML's rule language. Reading through this example will give you an idea of what XACML policies look like. These policies are human readable, but for the most part, they would be created using an access control-policy tool rather than being written by hand. We'll step through one.

The top-level element in an XACML policy is <Policy/>:

    <Policy
      PolicyId="SamplePolicy"
      RuleCombiningAlgId=
      "urn:...:xacml:1.0:rule-combining-algorithm:first-applicable">

The <Policy/> element contains a <Target/> element and zero or more <Rule/> elements. The <Target/> element defines the class of subjects, resources, and actions to which the policy is applied. The <Rule/> element defines an action, permit or deny, and the conditions under which that action is taken.

Here's an example of a <Target/> element that applies to any subject, and any action, on a resource identified by the string "SomeServer."

    <Target>
     <Subjects>
       <AnySubject/>
     </Subjects>
     <Resources>
      <Resource>
       <ResourceMatch
          MatchId="urn:...:xacml:1.0:function:string-equal">
         <AttributeValue>
             SampleServer
         </AttributeValue>
         <ResourceAttributeDesignator
             AttributeId="urn:...:xacml:1.0:resource:resource-id"/>
       </ResourceMatch>
      </Resource>
     </Resources>
     <Actions>
      <AnyAction/>
     </Actions>
    </Target>

Notice that operators and types are long and unwieldy in the style of XML-based languages. This is a reflection of the truth that XACML is not designed to be written by humans, but rather by programs. After the <Target/> element, the <Policy/> contains <Rules/>. The following two rules, taken together, require that a subject log in.

The first rule requires the login and further stipulates that it must be between the hours of 9 a.m. and 5 p.m. Its effect, given as an attribute to the <Rule/> element, is to Permit. The <Rule/> begins with an ID and its effect:

    <Rule RuleId="LoginRule" Effect="Permit">

The first part of any rule can be a target that is matched to determine whether this rule applies or not. Somewhat confusingly, these conditions are also called <Target/>. The following target ensures that this rule is used only when the action is "Login."

     <Target>
      <Subjects>
       <AnySubject/>
      </Subjects>
      <Resources>
       <AnyResource/>
      </Resources>
      <Actions>
       <Action>
        <ActionMatch
           MatchId="urn:...:xacml:1.0:function:string-equal">
         <AttributeValue
             Login
         </AttributeValue>
         <ActionAttributeDesignator AttributeId="ServerAction"/>
        </ActionMatch>
        </Action>
       </Actions>
      </Target>

Also included in the <Rule/> is a condition that enables the rule's action ("permit," in this case) only if the condition is true. The following condition is true only between 9 a.m. and 5 p.m.

      <Condition FunctionId="urn:...:xacml:1.0:function:and">
       <Apply
        FunctionId=
        "urn:...:xacml:1.0:function:time-greater-than-or-equal">
       <Apply
        FunctionId="urn:...:xacml:1.0:function:time-one-and-only">
        <EnvironmentAttributeDesignator
            AttributeId=
             "urn:...:xacml:1.0:environment:current-time"/>
       </Apply>
       <AttributeValue>
        09:00:00
       </AttributeValue>
      </Apply>
      <Apply
       FunctionId=
        "urn:...:xacml:1.0:function:time-less-than-or-equal">
       <Apply
        FunctionId="urn:...:xacml:1.0:function:time-one-and-only">
        <EnvironmentAttributeDesignator
          DataType="http://www.w3.org/2001/XMLSchema#time"
          AttributeId=
            "urn:...:xacml:1.0:environment:current-time"/>
       </Apply>
       <AttributeValue>
        17:00:00
       </AttributeValue>
      </Apply>
     </Condition>

This condition looks very complicated but is, in fact, quite simple when reduced to pseudocode:

    ($ENV(current_time) >= "09:00:00")
      AND ($ENV(current_time) <= "17:00:00")

If the first rule is inapplicable because of either its target or condition, then the default action, defined by the second rule, is to deny access (note that its effect attribute is Deny). Since it has no target or condition, this rule is always applicable.

    <!-- A final, "fall-through" Rule that always Denies -->
    <Rule RuleId="FinalRule" Effect="Deny"/>

The response generated from the application of this rule is simple, and contains a decision (Permit, in this case) and a status.

    <Response>
      <Result>
        <Decision>Permit</Decision>
        <Status>
          <StatusCode Value="urn:...:xacml:1.0:status:ok"/>
        </Status>
      </Result>
    </Response>

Since XACML is a complete declarative programming language, there is much more to it than can be covered in this simple example. XACML may not, in its present form, become the standard language of the PDP, but the problem is real and requires a standardized solution, and I'm convinced that XACML or something very similar to it will eventually be available for configuring policy on multiple systems from a single specification.