radac

Specification, Testing, and Verification of Risk Adaptable Access Control (RAdAC)

[Summary] [People] [Downloads]

PROJECT SUMMARY

Access control mechanisms are critical in maintaining privacy and securing data. Several approaches of access control exist, but most require policy writers to predict the risk involved in transactions that will occur in the future. Furthermore, most currently employed approaches do not account for changing risk. In a world where factors that determine risk are constantly changing and are difficult to predict, static policies are not sufficient. In modern networks, a more flexible model is desired. Risk Adaptable Access Control (RAdAC) proposed by NSA is a new access control model that weighs the security risk and operational need of each transaction. The result is a dynamic access control model that grants access based on the modern "need to share" paradigm. This project explores ways of specifying RAdAC policies in XACML, a popularly used specification language for access control policies, and develops techniques and tools for testing and verification of RAdAC security policies. We are currently looking into how policy testing and verification can be conducted under uncertainties inherent in risk management. We are exploring the use of multi-valued model checking on addressing this verification problem under uncertainties.

This project is part of the project on Testing and Verification of Security Policies.

PEOPLE

Faculty

Tao Xie

Collaborators

Vincent Hu, Rick Kuhn, and the ACTS group (NIST)

RAdAC POLICIES in XACML

RAdAC is still very much in the research phase, and specifying and enforcing RAdAC policies is essential in making the model succeed in practice. XACML is a modern specification language that was designed to support the specification and enforcement of generic access control policies. It is widely supported and adopted, making it a desirable policy language for specifying RAdAC policies. We next show how an RAdAC policy can be written in XACML.Then our effective testing and verification approaches for XACML can be applied on RAdAC policies.

An RAdAC policy must specify:

  • what factors contribute to security risk
  • an acceptable risk level for each area of risk (e.g., people, IT components, and objects) and for the composite risk
  • whether verification of operational need is required, and, if so, how to calculate it
  • whether operational need is allowed to trump security risk, and, if so, which areas of risk operational need may take precedence over and under what conditions.

The risk for several categories (e.g., characteristics of the requester, situational factors, and environmental factors) is computed. The risk associated with each category is then used to compute a composite risk. Each factor that contributes to risk or need is an attribute of either the subject, resource, action, or environment. Both security risk and operational need are numeric quantities. Thus, we can define thresholds for each risk category, the composite risk, and operational need.

In general, access control policies consist of a series of rules that take the following form:

If CONDITION Then

GRANT ACCESS

Else

DENY ACCESS

Writing RAdAC Rules in XACML

For an RAdAC policy, the CONDITION of a rule can be complex. To enable access to an object, risk must be lower than the thresholds described in the rule. Risk is calculated for several different areas, such as the risk associated with people, IT components, and the object being accessed. A rule checks that the risk associated with each of these areas, as well as the composite risk, is acceptable.

As as side note, security risk and operational need only need to be calculated ONCE. This way makes the calculations of the operational need and security risk ideal for the <VariableReference> and <VariableDefinition> elements, which evaluate a single block only once. However, these elements were introduced only in XACML 2.0.

The simplest CONDITION, which checks only for an acceptable risk, takes the following form:

(compositeRisk <= compositeRiskMax) AND (characteristicsOfRequester <= characteristicsOfRequesterMax) AND (characteristicsOfITComponents <= CharacteristicsOfITComponentsMax) AND ...

Next we show an example of an RAdAC policy in XACML. The maximum risk (and minimum need) has been chosen arbitrarily for all the examples described here and shall be specified by the policy writer.

<Condition>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="compositeRisk" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">45</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="characteristicsOfRequester" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">20</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="characteristicsOfITComponents" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">20</AttributeValue>

</Apply>

<-- and so on -->

</Condition>

If the risk for one or more areas is found to be unacceptable, operational need may trump security risk (if the policy writer desires so). To enable access to an object, need must be higher than the thresholds described in the rule. If operational need is able to trump security risk, the portion of the CONDITION that checks the risk for the particular area (in this case, characteristics of the requester) would look like below:

((characteristicsOfRequester <= characteristicsOfRequesterMax) OR (operationalNeed >= characteristicsOfRequesterOperationalNeedOverrideMin))

and in XACML:

<Condition>

...

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="characteristicsOfRequester" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">20</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">

<VariableReference VariableId="operationalNeed" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">40</AttributeValue>

</Apply>

</Apply>

...

</Condition>

Finally, if the security risk was found to be acceptable (after being overridden by operational need if necessary), the rule may still require checking of operational need before granting access. The CONDITION of a rule that requires checking of operational need takes the following form:

((compositeRisk <= compositeRiskMax) AND (characteristicsOfRequester <= characteristicsOfRequesterMax) AND ...) OR (operationalNeed >= operationalNeedMin)

and in XACML:

<Condition>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="compositeRisk" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">45</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">

<VariableReference VariableId="characteristicsOfRequester" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">20</AttributeValue>

</Apply>

<!-- and so on -->

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">

<VariableReference VariableId="operationalNeed" />

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">30</AttributeValue>

</Apply>

</Apply>

</Condition>

XACML is capable of specifying a subject (to determine whether the rule applies to the current situation) within each rule. We do not need to do anything special here. However, it is important to note that the example CONDITIONs given above should PERMIT access when the CONDITIONs are evaluated to be true. Due to this factor, all of the rules in the policies should have PERMIT as their effect (with one exception noted in the next section).

Writing RAdAC Policies in XACML

There are various ways to write policies in XACML. Any of the rule-combining and policy-combining algorithms that are native to XACML can be used to create complex policies and policy sets.

In our examples, we would like the policies to return permit or deny. This requirement can be accomplished by using the First-applicable rule-combining algorithm. However, we also need to end the policy with a tautology rule that denies all requests that have not already been matched by any of the previous rules.

<Policy PolicyId="radac-example" RuleCombiningAlgId="identifier:rule-combining-algorithm:first-applicable">

<!-- Rules go here -->

<!-- Tautology Rule -->

<Rule RuleId="Tautology" Effect="Deny" />

</Policy>

Security Risk Variables

In the code samples given so far, risk and need are variables, because security risk and operational need are used throughout the policy. More research needs to be done to find an appropriate technique of calculating risk and need. Since we currently use Sun's XACML Implementation, we can add our own functions to the specification. We use this way to create simple Java functions that return a numeric value of risk or need. For example, below is an example Java function that calculates the risk associated with the requester's clearance level:

public class ClearanceLevelRisk extends FunctionBase {

public static final String NAME = "characteristicsOfRequester-clearanceLevel";

public ClearanceLevelRisk() {

super(NAME, 0, StringAttribute.identifier, false, 1, 1, IntegerAttribute.identifier, false);

}

public EvaluationResult evaluate(List inputs, EvaluationCtx context) {

AttributeValue [] argValues = new AttributeValue[inputs.size()];

EvaluationResult result = evalArgs(inputs, context, argValues);

if (result != null)

return result;

StringAttribute str = (StringAttribute)(argValues[0]);

// Maximum risk if attribute has an unknown value

int evalResult = 100;

if (str.getValue().compareToIgnoreCase("Top Secret") == 0) {

evalResult = 20;

}

if (str.getValue().compareToIgnoreCase("Secret") == 0) {

evalResult = 40;

}

if (str.getValue().compareToIgnoreCase("Confidential") == 0) {

evalResult = 60;

}

if (str.getValue().compareToIgnoreCase("No Clearance") == 0) {

evalResult = 80;

}

return new EvaluationResult(new IntegerAttribute((long)evalResult));

}

}

Much of this code is similar for every risk/need factor, because a single argument and an integer return value are needed by functions for all risk/need factors. It is important to note that the example above is trivial and is not sufficient for real-world measurement of risk. In practice, the function would likely be more mathematically involved and may also take into account the history information. For example, the risk associated with a transaction involving someone with "Top Secret" clearance may be related to the total number of incidents involving all people with "Top Secret" clearance. The more incidents, the higher the risk associated with the "Top Secret" clearance level. For this example, we assume that a higher clearance poses less risk, but in real life this assumption may not be realistic. In any case, we can now reference the function in the XACML policy.

The risk for a particular area is calculated as follows (in this case, characteristics of the requester):

<VariableDefinition VariableId="characteristicsOfRequester">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-divide">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-add">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-role">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-role" DataType="http://www.w3.org/2001/XMLSchema#string" />

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-rank">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-rank" DataType="http://www.w3.org/2001/XMLSchema#string" />.

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-clearanceLevel">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-clearanceLevel" DataType="http://www.w3.org/2001/XMLSchema#string" />

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">20</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-accessLevel">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-accessLevel" DataType="http://www.w3.org/2001/XMLSchema#string" />

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-previousViolations">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-previousViolations" DataType="http://www.w3.org/2001/XMLSchema#string" />

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<Apply FunctionId="radac-risk-characteristicsOfRequester-educationLevel">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

<SubjectAttributeDesignator AttributeId="characteristicsOfRequester-educationLevel" DataType="http://www.w3.org/2001/XMLSchema#string" />

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">1</AttributeValue>

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">51</AttributeValue>

</Apply>

</VariableDefinition>

In the example above, the risk associated with each factor is multiplied by its relative weight. The sum of all the weighted factors are then divided by the sum of the relative weights, producing a total risk measurement for this area. Writing the policy in this way allows us to omit factors if they are irrelevant, and control the weight of each factor within the area. The disadvantage of doing so, however, is that it is easy to accidentally omit a factor, or sum the relative weights incorrectly. In addition, if a more complex way of combining factors is chosen, it might not be easily written in XACML.

After the risk for each area is calculated, we must now calculate the composite risk. The calculation is done in a similar fashion, only instead of using weighted factors, we use the risk associated with each area (also weighted). An example calculation is shown as below:

<VariableDefinition VariableId="compositeRisk">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-divide">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-add">

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="characteristicsOfRequester"/>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="characteristicsOfITComponents"/>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="situationalFactors"/>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="environmentalFactors"/>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="characteristicsOfInformationRequested"/>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>

</Apply>

<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-multiply">

<VariableReference VariableId="http://www.w3.org/2001/XMLSchema#integer">3</AttributeValue>

</Apply>

</Apply>

<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">38</AttributeValue>

</Apply>

</VariableDefinition>

In the code sample above, the risk associated with each area is multiplied by its relative weight. The sum of all the weighted areas is then divided by the sum of their relative weights, producing a composite risk measurement.

Operational Need Variables

The factors that contribute to need are similar to those used to calculate risk. If we calculate need in the same way that we calculate risk, we could use a function, as shown below, to calculate the operational need associated with a person's location:

public class LocationNeed extends FunctionBase {

public static final String NAME = "operationalNeed-Location";

public LocationNeed() {

super(NAME, 0, StringAttribute.identifier, false, 1, 1, IntegerAttribute.identifier, false);

}

public EvaluationResult evaluate(List inputs, EvaluationCtx context) {

AttributeValue [] argValues = new AttributeValue[inputs.size()];

EvaluationResult result = evalArgs(inputs, context, argValues);

if (result != null)

return result;

StringAttribute str = (StringAttribute)(argValues[0]);

// Minimum need if attribute has an unknown value

int evalResult = 0;

if (str.getValue().compareToIgnoreCase("USA") == 0) {

evalResult = 80;

}

if (str.getValue().compareToIgnoreCase("Canada") == 0) {

evalResult = 75;

}

if (str.getValue().compareToIgnoreCase("Mexico") == 0) {

evalResult = 50;

}

return new EvaluationResult(new IntegerAttribute((long)evalResult))

}

}

In the above code sample, a person who is located in the USA has a higher operational need to have access to the resource in question. As with the security risk calculations, a real-world need calculation may likely be more complex. Operational need factors are combined the same way risk factors are.

REFERENCES

We use risk factors as suggested by David W. Britton and Ian A. Brown in their thesis entitled "A Security Risk Measurement for the RAdAC Model," published in March 2007. Risk factors, their categories, and their possible values we use in our examples were inspired, in part, by their paper.

DOWNLOADS

  • Sun's XACML Implementation required to be a PDP for evaluating a request against a RAdAC policy in XACML
  • An example RAdAC policy in XACML (radac_pol.xml)
  • Example Java functions referenced by the example RAdAC policy (risk_need_factors.zip)
  • Example requests to be evaluated against the example RAdAC policy (radac_low_req.xml, radac_high_req.xml)
    • Note that both requests are evaluated against radac_pol.xml. One request is an example of a 'low' risk scenario, and the other is a 'high' risk scenario.
  • Example responses produced by PDP for the example requests against the example RAdAC policy (response_radac_low_req.txt, response_radac_high_req.txt)