I would like to point out a few issues with XACML and time.
These affect XACML 1.0 and the current draft for XACML 1.1.
First, some background. I have often heard people ask
for the ability to only allow access to a resource during
certain hours (e.g., 9 AM to 5 PM local time). So it seems
that this is something you might want to support in XACML.
Unfortunately, it's not easy to do this in XACML. The
attached policy seems like it would only allow logins
from 9:00 AM to 5:00 PM (using the current time at the
PDP as a reference). But this won't work. XACML defines
the function time-greater-than-or-equal to use the order
relation "specified for http://www.w3.org/2001/XMLSchema#time".
And that order relation cannot compare times if one of
the times has a time zone and one does not. In the example,
current-time has the time zone of the PDP and the times
specified in the policy have no time zone. Presumably,
the function returns Indeterminate in that case.
This is especially odd since XACML defines time-equal to be
equivalent to "the 'op:time-equal' function [XF Section 8.3.14]."
This function *does* allow comparing times when one of
the times has a time zone and one does not. It simply
specifies that the time without a time zone should be
assigned an implicit time zone (generally the local time
zone).
Can this problem be fixed by specifying a time zone for the
times specified in the policy (the AttributeValues)? That
has the disadvantage of tying the policy to the specific
time zone of the PDP, meaning that you can't use one policy
to handle multiple time zones. In fact, you must update the
policy whenever you change to Daylight Savings Time. But set
that aside. Look at policy2.xml, which adds a time zone.
Making this change does fix the problem, unless you are in
the Far East. If midnight GMT is between 9:00 AM and 5:00 PM
in the PDP's time zone, then the policy always denies
access. Surprising, eh? The reason is that the order
relation specified by XML Schema for times says that you
normalize the times to GMT and then compare them, with
midnight GMT being the earliest time and 23:59:59 being
the latest. If midnight GMT is noon local time, then the
revised policy will only grant access is the current time
is after 9:00 PM GMT and before 5:00 AM GMT. That can't
ever happen.
So how can this problem be addressed? If midnight GMT is
between 9:00 AM and 5:00 PM in the PDP's time zone, you
must rewrite the policy to say that access is granted if
the current time is after 9:00 AM *OR* before 5:00 PM in
the local time zone. That's pretty odd!
How can you fix these problems? I have a few recommendations.
1) Consider changing the comparison functions for date, time,
and dateTime to be equivalent to the functions defined
in XQuery. This will allow them to handle comparing
a value with no time zone with a value with a time zone.
If it's too late to make this change, at least add a warning
in the spec about this problem.
2) Define a new time-in-range function that takes three time
arguments and returns true if the first one falls between
the other two (on or after the second time and on or before
the third time). If no time zone is specified for the second
or third arguments, treat them as if they are in the time zone
of the first argument. Then you could say
time-in-range(current-time, 9:00:00, 17:00:00)
to check whether the PDP-local time is between 9 AM and 5 PM
in the PDP-local time zone (regardless of where the PDP-local
time zone is relative to GMT).
This would make it easy to solve the most common problem and
get it right without having to understand a lot about
times and dates, spend a lot of time changing your policy
for different time zones, etc.
Thanks,
Steve Hanna
<?xml version="1.0" encoding="UTF-8"?>
<Policy
xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:1.0:policy
cs-xacml-schema-policy-01.xsd"
PolicyId="SamplePolicy"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<!-- This Policy only applies to requests on the SampleServer -->
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<Resource>
<ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleServer</AttributeValue>
<ResourceAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>
</ResourceMatch>
</Resource>
</Resources>
<Actions>
<AnyAction/>
</Actions>
</Target>
<!-- Rule to see if we should allow the Subject to login -->
<Rule RuleId="LoginRule" Effect="Permit">
<!-- Only use this Rule if the action is login -->
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<Action>
<ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">login</AttributeValue>
<ActionAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="ServerAction"/>
</ActionMatch>
</Action>
</Actions>
</Target>
<!-- Only allow logins from 9am to 5pm -->
<Condition FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
<EnvironmentAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#time"
AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">09:00:00</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
<EnvironmentAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#time"
AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">17:00:00</AttributeValue>
</Apply>
</Condition>
</Rule>
<!-- We could include other Rules for different actions here -->
<!-- A final, "fall-through" Rule that always Denies -->
<Rule RuleId="FinalRule" Effect="Deny"/>
</Policy>
<?xml version="1.0" encoding="UTF-8"?>
<Policy
xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:1.0:policy
cs-xacml-schema-policy-01.xsd"
PolicyId="SamplePolicy2"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<!-- This Policy only applies to requests on the SampleServer -->
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<Resource>
<ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleServer</AttributeValue>
<ResourceAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>
</ResourceMatch>
</Resource>
</Resources>
<Actions>
<AnyAction/>
</Actions>
</Target>
<!-- Rule to see if we should allow the Subject to login -->
<Rule RuleId="LoginRule" Effect="Permit">
<!-- Only use this Rule if the action is login -->
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<Action>
<ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">login</AttributeValue>
<ActionAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="ServerAction"/>
</ActionMatch>
</Action>
</Actions>
</Target>
<!-- Only allow logins from 9am to 5pm EDT -->
<Condition FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
<EnvironmentAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#time"
AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">09:00:00-04:00</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
<EnvironmentAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#time"
AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">17:00:00-04:00</AttributeValue>
</Apply>
</Condition>
</Rule>
<!-- We could include other Rules for different actions here -->
<!-- A final, "fall-through" Rule that always Denies -->
<Rule RuleId="FinalRule" Effect="Deny"/>
</Policy>