A REST API for XACML

The wonderful book RESTful Web Services describes a procedure for developing RESTful web services. In this post, we will apply this procedure to XACML.

The eXtensible Access Control Markup Language (XACML) describes an architecture for authorization. The components of the architecture that are of interest to us here are the Policy Decision Point (PDP) and Policy Administration Point (PAP). The PDP is the component that decides on an authorization request. The PAP is the component that maintains the authorization policies that the PDP uses to reach its decision. There are more components in the architecture, but from a web services standpoint, the PAP and PDP give a client everything it needs to write and evaluate authorization policies.

Resources
Key to the REST architectural style is to identify resources and name them with URIs. The book states that “A resource is anything interesting enough to be the target of a hypertext link.” There are three different types of resources:

  • Predefined one-off resources for especially important aspects of the application
  • Resources for every object in the data set the service exposes
  • Resources representing the results of algorithms applied to the data set

An example of a predefined one-off resource is the list of XACML policies. We name that resource with the URI /policies. Note that this is a relative URI, the actual URI will be something like http://www.example.com/application/policies. In this post we will show relative URIs only.

An application can have many policies, which means the response could become very large. We solve that problem using pagination: we will return a small number of results only. If a client wants more results, it can use query parameters to do so: /policies?offset=100&count=20.

Resources from the data set that our service exposes are the individual XACML policies. We name policies with the URI /policies/{policyId}, where the part between {} is variable. We could even go a step further and include finer-grained resources like rules, attributes, and conditions. Their URIs would be /policies/{policyId}/{ruleId}, etc.

An example of a resource that is the result of an algorithm is the PDP’s access decision, which we arrive at by matching the policies with the request attributes. This resource is a bit trickier to name, since we need to supply input to it, which is usually accomplished using query parameters. So we could name this resource with the URI /decision?attribute1=value1&attribute2=value2&... A XACML attribute is identified by multiple pieces of information: category, id, and data type. We could encode these in a query parameter name using the scheme {category}/{id};{dataType}. Here we follow the convention that / implies hierarchy, while ; implies unordered combination.

However, with categories like urn:oasis:names:tc:xacml:1.0:subject-category:access-subject, ids like urn:oasis:names:tc:xacml:1.0:subject:subject-id, and data types like urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name, the URI will grow very big very quickly. There is no theoretical limit to URI length, but many applications will enforce limits in practice. (There is even an HTTP status code for this situation.) So we will need a way to shorten the URI considerably.

One way to do that, is to define shortcuts for standard attributes. For instance, instead of writing urn:oasis:names:tc:xacml:1.0:subject-category:access-subject/urn:oasis:names:tc:xacml:1.0:subject:subject-id,urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name, we could just use subject. To avoid conflicts, these shortcuts would have to be standardized along with the REST API.

The other potential problem with this approach is that / and ; are valid parts of URIs, and therefore could be used in categories, ids, and data types. The chances of this happening are not very high, though. The XACML specification uses : to separate components, and extensions would be wise to follow that example. Otherwise, they could use percent encoding.

Uniform Interface
The next step is to determine what operations are allowed on what resources. In a RESTful architecture, operations use the HTTP verbs only. This is called the uniform interface. We must identify the HTTP verbs supported for each URI, and also determine what HTTP status codes they return.

The list of policies, /policies, only supports GET, to retrieve the policies. There is no need to support POST to create policies: policies are named by ID, and the ID is part of the content, so it must be known to the client. This method will always return 200 OK if the server is operating fine. Otherwise, a 500 Internal Server Error will be returned. This last status is returned for all methods on all resources when there is a problem with the server, so we will not mention it any further.

PUT on /policies/{policyId} creates a new policy, or overwrites an existing policy. GET retrieves a policy and DELETE removes it. GET will return either 200 OK or 404 Not Found. PUT and DELETE will normally return 204 No Content. PUT can additionally return 415 Unsupported Media Type when the representation in the request (see below) is not understood.

The /decision resource, being algorithmic, only supports GET. Possible return codes are 200 OK, or 400 Bad Request when a parameter is invalid. This could happen when an unknown category, id, or data type is specified, or when the value supplied doesn’t match the data type. It can also happen when an unknown shortcut is used to identify a variable.

Like all web services, a XACML PAP needs to be secured. Whatever means used for that is out of scope for this discussion, but there are some additional status codes that the web service may return, irrespective of the security means. 401 Unauthorized means that the user making the request didn’t provide sufficient credentials, while 403 Forbidden means that the user doesn’t have the privileges required to honor the request.

Representations
The next step is to design the representations of the resources. There are two such representations: those presented to the server by the client, and those returned to the client by the server.

Clients don’t always have to provide content to the web services. Only PUT on /policies/{policyId}/ requires input, namely the policy. The representation of a policy should simply follow the XML format that the XACML standard prescribes. There is no media type registered for XACML at IANA, so we’ll have to make do with text/xml.

The representations returned by the server are a bit trickier. First there is the list of policies returned by /policies. This service could either return all the policies in XACML format, or only the IDs. Chances are this service is invoked to determine which policies exist. It’s not clear that their details are always required, so it may make more sense to just return the IDs, since that keeps the response leaner. Atom is always a good representation for lists of entries with links, but XACML 3.0 has a construct named PolicyIdentifierList that specifically represents a list of policy IDs. We should use that instead of Atom, since it’s extremely likely that the client can already parse XACML, but not that they can also parse Atom.

In order for representations to drive the state, which is the point in REST, they should contain links to other resources. So /policies should return not just IDs, but also links to the policies identified by those IDs. PolicyIdentifierList doesn’t provide for that, however. But we can augment it using the standard way of linking in XML: XLink. An example would be:

<PolicyIdentifierList xmlns:xlink='http://www.w3.org/1999/xlink
    xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
  <PolicyIdReference xlink:href="/policies/urn:sample:policy:id">urn:sample:policy:id</PolicyIdReference>
</PolicyIdentifierList>

The result of GET on /policies/{policyId} should simply be the XACML policy in the canonical XML format. The issue of linking comes up here as well, so we’ll use XLink again. For instance, a policy set can contain a PolicyIdReference.

The result of /decision is a XACML decision, i.e. one of Permit, Deny, NotApplicable or Indeterminate. We should represent that with the XACML Decision XML element, since the client can likely already parse that.

So this is my proposal for a REST API for XACML. What do you think?

Update: There is now an official REST Profile for XACML.

Advertisements

2 thoughts on “A REST API for XACML

  1. Hi,
    with regard to the “resources”-bit, could you use a payload to solve the trouble with the representation of the attributes/categories?
    That way you execute a GET /decision with the rest of the arguments as an JSON or XML payload?

    Bob

    1. GETs usually don’t supply bodies, so my preference would be not to do it. But it’s certainly a possibility.

Please Join the Discussion

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s