How To Write XACML Policies – Part 1 (Simple Policy Editor)

WSO2 Identity server  provides a XACML policy editors for creating XACML 3.0 policies. Actually WSO2 Identity server 4.5.0 has been shipped with three policy editors. One is simple policy editor that is going be discussed today  and others are basic policy editor and standard policy editor.  In this blog post, i am going to share some knowledge about simple policy editor

What is  “Simple Policy Editor” ?

It is said as simple policy editor. Because You can create XACML 3.0 policies without any knowledge of XACML policy language. You can define your rules in a simpler manner and create a XACML 3.0 policy out of them. However you need to have some knowledge about access control rules.

First lets try to understand what options are provided by this editor.

This editor is based on four categories which we are mostly talking in access control rules. i.e User, Resource, Action and Environment.

Resource is entity that we are trying to protect with access control rules. In SOA, it can be just a web service name

User is the person who is going to access the resource

Action is, what user is going to perform on Resource. Basically it can be read, write, view or any thing that can be performed on resource.

Environment is the time, domain or any other factors that could cause to control the user’s access

XACML 3.0 is not bound to these four categories. There can be many. But using this policy editor, It has been limited to create XACML 3.0 policies with these four categories. Using this editor, policy can be defined, based on an one category.  “based on” means; Say you are writing an access control policy. You need to say “for what i am writing this policy?” Basically the entity that you are defining the policy. You may writing policy for your web service or for a role and so on…

Following is the screenshot of this policy editor, as you can see it is simpler UI.

Things to remember on “Simple Policy Editor”

Here, you need to remember following facts,

Fact 1. You can define a policy name.

Fact 2. You can define a policy description

Fact 3. You can define; based on what entity, that you are going to write this policy. If you are writing policy based on web service. You can select “Resource” category and continue. Or less, if you are writing policy based on email domain of users. You can select “Subject” category and select the “Email” attrubute Id and then define the email

Fact 4. You can define multiple permit rules. As an example, “Only users in admin role can do GET” This rule can be defined as following

You need to select “Role” attribute id for “User” and fill the text box with the role name (admin) and then fill the text box of near “Action” with action name (GET)

Fact 5. Deny rule is automatically created as the final rule. Permitted rules are evaluated from top to blow.

Fact 6. When you are filling text box with values. Followings are important.

  • If you want to define value as java regexp expression, you need to embedded value in the curly brackets “{ }”

Ex :  { ^([a-zA-Z0-9_.-])[email protected] }

  • If you want to define multiple values as OR or AND value sets. you can separate those multiple values with “|” or “&” separates

Ex : read | write | delete

Ex : ReadRole & WriteRole

  • If you want to define value as a greater or lesser than value. you can use “<” or “>”

Ex  :  < 34

Note : I guess, unfortunately greater than equal and lesser than equal options are missed.

  • If you want to define two values that are in a range, you can use square brackets “[ ]” and round brackets “(  )” . And two values are coma “, “ separated.

Ex:  [09:00:00+05:00, 16:00:00+05:00]      time between 09.00am and 04.00 pm

Ex: (18, 30]     greater than 18 and less than or equal to 30

Writing sample policy

Assume;

  • Policy is defined for accessing “foo” resource

following are the access control rules that policy needs to be satisfied

  • Resources under “foo” collection can be read, written, edited and deleted by the users in admin role.
  • Resources under “foo/wso2″ collection can be read by only the users in the WSO2 (whose email address is wso2.com domain) between 9.00am and 4.00pm.
  • All other access request to “foo” resource must be denied.

Following is the screenshot of simple policy editor with defined rules.

In 1st rule followings are defined

User -> “Role” selected and “admin” value is in text box
Action -> Actions values are in text box by separated with OR “read | write | delete”

In 2nd rule followings are defined

User —> “Email” selected and “^([a-zA-Z0-9_.-])[email protected]” value is in text box with curly brackets (as it is java regexp)
Action -> “read” value is in text box
Environement -> “Time” has been selected and “09:00:00+05:00, 16:00:00+05:00” is defined with squred brackets (as it is a range). Here “+05:00” is offset from GMT

Following is the policy that is created.

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="MyPolicy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
 <Description>saascsac</Description>
 <Target>
 <AnyOf>
 <AllOf>
 <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match">
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">foo//*</AttributeValue>
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Match>
 </AllOf>
 </AnyOf>
 </Target>
 <Rule Effect="Permit" RuleId="Rule-1">
 <Condition>
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">delete</AttributeValue>
 </Apply>
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Apply>
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
 <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue>
 <AttributeDesignator AttributeId="http://wso2.org/claims/role" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Apply>
 </Apply>
 </Condition>
 </Rule>
 <Rule Effect="Permit" RuleId="Rule-2">
 <Target>
 <AnyOf>
 <AllOf>
 <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">foo/wso2</AttributeValue>
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Match>
 </AllOf>
 </AnyOf>
 <AnyOf>
 <AllOf>
 <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Match>
 </AllOf>
 </AnyOf>
 </Target>
 <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:time-greater-than-or-equal">
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#time" MustBePresent="true"/>
 </Apply>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">09:00:00+05: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">
 <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#time" MustBePresent="true"/>
 </Apply>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">16:00:00+05:00</AttributeValue>
 </Apply>
 </Apply>
 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
 <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"/>
 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">^([a-zA-Z0-9_.-])[email protected]</AttributeValue>
 <AttributeDesignator AttributeId="http://wso2.org/claims/emailaddress" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
 </Apply>
 </Apply>
 </Condition>
 </Rule>
 <Rule Effect="Deny" RuleId="Deny-Rule"/>
</Policy>