In a previous post, I talked about one of the most advanced access control models to date: Risk-Adaptive Access Control. In this post, I will put this in context by taking a closer look at a variety of access control models.
Access Control Defined
Access control is all about permitting or denying access requests. An access request occurs when:
a given subject tries to access
a given resource to perform
a given action in
a given environment.
Access Control Lists (ACLs) (subject, resource, action, N/A)
The subject is either a user or a group. In some cases it can be an application.
ACLs are hard to maintain when many users share privileges. For example, all developers should have access to the source code management (SCM) system. If the SCM is upgraded with a new feature that has its own permission, then the ACLs for all developers must be updated.
ACLs are widely available, for instance in operating systems.
Role-Based Access Control (RBAC) (role, resource, action, N/A)
Users are now generalized into roles, like developer.
Roles are often not granular enough. For example, only the developers for product X should have access to the product X SCM. This can be fixed by introducing finer-grained roles, but that often leads to an explosion of roles. Sometimes there are even more roles than users in a system!
RBAC is commonly available, for instance in relational databases.
Attribute-Based Access Control (ABAC) (subject, resource, action, environment)
Everything is now generalized into attributes. Environment attributes, like the current time, are now also supported.
Attributes are often used differently in different applications. For instance, one application may name the attribute for role role, while another may use role-id. Or one application may use an ID into a role table as the value of the role attribute, while another uses the role’s human readable name.
ABAC is considered state of the art.
Policy-Based Access Control (PBAC) (subject, resource, action, environment)
Attributes are now harmonized across all applications of the (extended) organization. For instance, the Core and Hierarchical Role Based Access Control (RBAC) Profile for XACML defines the URNurn:oasis:names:tc:xacml:2.0:subject:role for the role attribute.
We’re just starting to see some PBAC implementations.
Risk-Adaptive Access Control (RAdAC) (subject, resource, action, environment)
The environment attributes now take on a much more important role. In particular, dynamic risk levels are encoded as attributes.
I know of no implementations of RAdAC, but I think we’ll start seeing them soon(ish), since they can help in the fight against Advanced Persistent Threats.
Trends in Access Control Model Evolution
If you look closely at this mostly chronological development of access control models, you’ll find the following trends:
Access control becomes more fine-grained
Access control becomes more policy-based, less ad-hoc
Access control becomes external to applications
XACML Supports All Major Access Control Models
The eXtensible Access Control Markup Language (XACML) is an OASIS standard for ABAC. Since ABAC is a generalization of RBAC, and RBAC is a generalization of ACLs, it’s not surprising that XACML can handle all of those access control models. Furthermore, PBAC is technically just ABAC. The PDP doesn’t care what attributes are used, or how they are named. Nor does it care whether does attributes represent dynamic risk levels, as in RAdAC.
So the conclusion is that XACML supports all the major access control models. This makes XACML a future-proof technology. It will easily accompany you on your journey to a more sophisticated access control model.
What I mean by that is that you will never get kudos for implementing a secure system, but you certainly will get a lot of flak for an insecure system, as the recent LinkedIn incident shows. Therefore, security is a distraction for most developers; they’d rather focus on their core business of implementing features.
Where have we heard that before?
Cloud Computing to the Rescue: SecaaS
Cloud computing promises to free businesses from having to buy, install, and maintain their own software and hardware, so they can focus on their core business.
The alternative of using libraries, while infinitely better than rolling our own, is less attractive than the utility model. We’d still have to update the libraries ourselves. Also, with libraries, we depend on a language level API, which segments the market, making it less efficient.
There are some hurdles to tackle before SecaaS will go mainstream. Let’s take a look at one issue close to my heart.
Each type of security service should have one or at most a few standards, to level the playing field for vendors and to allow for easy switching between offerings of different vendors.
For authorization, I think we already have such a standard: XACML.
We also need a more general standard that applies to all security services, so that we have a simple programming model for integrating different security services into our applications. I believe that standard should be REST. Update: The market seems to agree with this. Just see the figures in this presentation.
This is one of the reasons why we’re working on a REST profile for XACML. Stay tuned for more information on that.
So what do you think about SecaaS? Let me know in the comments.
Risk-Adaptive Access Control (RAdAC) is an advanced access control model where access decisions depend on dynamic risk assessments. In this post, I’ll show how RAdAC can be used in the fight against Advanced Persistent Threats (APTs).
Before I make that point, let me start off with a simple illustration of RAdAC in action. Then I’ll show how to implement RAdAC using eXtensible Access Control Markup Language (XACML).
In the default situation, the threat level is at green, and the user is able to see and edit a document:
However, when the threat level goes to yellow, the user is no longer able to edit the document:
Finally, when the threat level goes to red, the user can’t even see the document anymore:
Using XACML to Implement Risk-Adaptive Access Control
The demo may be simplistic, but it is a fully working system based on XACML. And, not unimportant from a software development perspective, it was very easy to build.
Remember the XACML architecture:
Given this architecture, all we need (from a technical perspective) to support RAdAC is a Policy Information Point (PIP) that looks up the dynamic risk attributes (environment oval in the above diagram). Once we have that, these attributes can be used in access control policies like any other attribute (subject-id, role, resource-id, action-id, etc, etc.)
In the demo, the threat level is set by clicking the traffic light. In the real world, a PIP would be connected to an Intrusion Detection System so that it can calculate the value of the threat level attribute.
The nice thing with an access control architecture based on XACML, is that no software needs to be updated to support RAdAC. All we need is to hook up the Policy Decision Point (PDP) to a PIP that calculates the threat level. You could go finer-grained as well, and split the one threat level attribute into several, if that’s what your access control policies require. How you write your policies has no impact on your applications, since the PDP and PIP can be re-used across all applications in your organization.
Risk-Adaptive Access Control and the Fight Against Advanced Persistent Threats
I think it won’t be long before we’ll start seeing implementations of RAdAC, since it can be a big help in the struggle against APTs.
With RAdAC, we make decisions up front about what to do in the event of an intrusion, and formalize those decisions in automated access control policies. Then when a security incident occurs, we can focus our energy on getting the intruder off the system instead of on protecting our information assets, since that will already have been taken care of.
What do you think? Is your organization interested in solutions like these in the fight against APTs? Please share your thoughts in the comments.
The OASIS Technical Committee that defines the XACML specification recently voted version 3.0 to Committee Draft Specification. A public review will follow and then the spec will move to Committee Specification and from there to Standard.
To become an OASIS standard, there must be at least three attestations of successful use of a specification. We recently got the third attestation from the Bank of America, so things are looking good on the standardization front.
XACML in the Market
But how is the market responding? I don’t have a good overview of global XACML adoption. I did, however, recently attend an XACML seminar in the Netherlands, which gave me a good impression of XACML adoption in the low countries.
Martijn Kaag talked about the use of XACML in eRecognition (eHerkenning), which provides authentication and authorization services for businesses and government agencies. It is required for all Dutch national, regional and local government agencies.
Oscar Koeroo talked about the use of XACML in the academic grid computing world. This is a spectacular infrastructure for particle physics research. Talking about Big Data! They make heavy use of XACML obligations.
Maarten Wegdam talked about an XACML pilot at a large Dutch bank, where they relied a lot on context information, mostly having to do with location. This context is stored in XACML environment attributes.
Conclusion
Things are definitely moving in the right direction, but XACML still seems confined to some isolated cases. It may take some time before we see widespread use. Until that time, we can learn from a couple of interesting places where people are pioneering with XACML.
At the recent RSA conference, five organizations participated in an interop for the eXtensible Access Control Markup Language (XACML), based on version 3.0 of the XACML core spec and the Intellectual Property Control profile that is currently being defined. The interop was a big success, but its significance goes beyond the conference. So far, two organizations have formally attestedconformance to XACML 3.0, but the interop featured five parties. This makes it likely that a third attestation is very close, and only three attestations are required before a specification can become an official OASIS standard.
There are other signals as well that XACML is doing well. Many people and organizations seem interested enough that they want to start experimenting with it, and many more are seriously contemplating that.
And that makes sense to me (although I’m obviously biased). One reason is the impact that cloud computing is making, since XACML is perfect for use in the cloud. And adoption in cloud scenarios will become even easier with the REST and media types profiles that are currently being defined.
All in all, I have a feeling that a breakthrough is in the air.
If you’re interested in XACML yourself, and you live in or close by the Netherlands, then there is a good opportunity for you to learn more about how XACML is used in practice at the upcoming seminar in Utrecht on April 26. The program for this full day event is almost finalized and ranges from the abstract (how does XACML fit in a security architecture) to the very concrete (experience reports from real implementations) and everything in between, like a demonstration from XACML vendor Axiomatics. Two members of the XACML Technical Committee will be there, so seize this opportunity to ask all and any questions you may have! The presentations will be in English, but most presenters also speak Dutch. Follow this seminar on Twitter via #xacmlnl.
So, what do you think? Do you see more implementations around you? Do you have a feeling that you need to know more about this important access control standard? Let me know in the comments.
Test-Driven Development (TDD) is a scientific approach to software development that supports incremental design. I’ve found that, although very powerful, this approach takes some getting used to. Although the rules of TDD are simple, they’re not always easy:
Write a failing test
Write the simplest bit of code that makes it pass
Refactor the code to follow the rules of simple design
This is also called the Red-Green-Refactor cycle of TDD.
Writing a failing test isn’t always easy. Lots of TDD beginners write tests that are to big; TDD is all about taking baby steps. Likewise, writing the simplest bit of code to make the test pass is sometimes difficult. Many developers are trained to write generic code that can handle more than just the case at hand; they must unlearn these habits and truly focus on doing The Simplest Thing That Could Possibly Work.
The hardest part of TDD, however, is the final step. Some TDD novices skip it altogether, others have trouble evolving their design. Code that follows the rules of simple design
Passes all the tests
Contains no duplication
Clearly expresses the programmer’s intent
Minimizes code
The first is easy, since your xUnit framework will either give you Red or Green. But then the fun begins. Let’s walk through an example to see TDD in action.
In the Roman Numerals kata, we convert Arabic numbers (the one we use daily: 1, 2, 3, 4, 5, …) into their Roman equivalent: I, II, III, IV, V, … It’s a good kata, because it allows one to practice skills in a very concentrated area, as we’ll see.
So let’s get started. The first step is to write a failing test:
public class RomanNumeralsTest {
@Test
public void one() {
Assert.assertEquals("1", "I", RomanNumerals.arabicToRoman(1));
}
}
Note that this step really is not (only) about tests. It really is about designing your API from the client’s perspective. Think of something that you as a user of the API would like to see to solve your bigger problem. In this kata, the API is just a single method, so there is not much to design.
OK, we’re at Red, so let’s get to Green:
public class RomanNumerals {
public static String arabicToRoman(int arabic) {
return "I";
}
}
But that’s cheating! That’s not an algorithm to convert Arabic numerals into Roman! True, it’s not, but it isn’t cheating either. The rules of TDD state that we should write the simplest code that passes the test. It’s only cheating if you play by the old rules. You must unlearn what you have learned.
Now for the Refactor step. The test passes, there is no duplication, we express our intent (that currently is limited to convert 1 into I) clearly, and we have the absolute minimum number of classes and methods (both 1), so we’re done. Easy, right?
Now we move to the next TDD cycle. First Red:
public class RomanNumeralsTest {
@Test
public void oneTwo() {
Assert.assertEquals("1", "I", RomanNumerals.arabicToRoman(1));
Assert.assertEquals("2", "II", RomanNumerals.arabicToRoman(2));
}
}
No need to change our API. In fact we won’t have to change it again for the whole kata. So let’s move to Green:
public static String arabicToRoman(int arabic) {
if (arabic == 2) {
return "II";
}
return "I";
}
OK, we’re Green. Now let’s look at this code. It’s pretty obvious that if we continue down this path, we’ll end up with very, very bad code. There is no design at all, just a bunch of hacks. That’s why the Refactor step is essential.
We pass the tests, but how about duplication? There is duplication in the Arabic number passed in and the number of I’s the method returns. This may not be obvious to everyone because of the return in the middle of the method. Let’s get rid of it to better expose the duplication…
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
if (arabic == 2) {
result.append("I");
}
result.append("I");
return result.toString();
}
…so that we can remove it:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < arabic; i++) {
result.append("I");
}
return result.toString();
}
What we did here was generalize an if statement into a for (or while). This is one of a bunch of transformations one often uses in TDD. The net effect of a generalization like this is that we have discovered a rule based on similarities. This means that our code can now handle more cases than the ones we supplied as tests. In this specific case, we can now also convert 3 to III:
Now that we have removed duplication, let’s look at expressiveness and compactness. Looks OK to me, so let’s move on to the new case. We got 3 covered, so 4 is next:
@Test
public void four() {
Assert.assertEquals("4", "IV", RomanNumerals.arabicToRoman(4));
}
This fails as expected, because we generalized to far. We need an exception to our discovered rule:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
if (arabic == 4) {
return "IV";
}
for (int i = 0; i < arabic; i++) {
result.append("I");
}
return result.toString();
}
This uses return in the middle of a method again, which we discovered may hide duplication. So let’s not ever use that again. One alternative is to use an else statement. The other is to decrease the arabic parameter, so that the for loop never executes. We have no information right now on which to base our choice, so either will do:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
if (arabic == 4) {
result.append("IV");
} else {
for (int i = 0; i < arabic; i++) {
result.append("I");
}
}
return result.toString();
}
It’s hard to see duplication in here, and I think the code expresses our current intent and is small, so let’s move on to the next test:
@Test
public void five() {
Assert.assertEquals("5", "V", RomanNumerals.arabicToRoman(5));
}
Which we make pass with:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
if (arabic == 5) {
result.append("V");
} else if (arabic == 4) {
result.append("IV");
} else {
for (int i = 0; i < arabic; i++) {
result.append("I");
}
}
return result.toString();
}
This is turning into a mess. But there is no duplication apparent yet, and the code does sort of say what we mean. So let’s push our uneasy feelings aside for a little while and move on to the next test:
@Test
public void six() {
Assert.assertEquals("6", "VI", RomanNumerals.arabicToRoman(6));
}
Which passes with:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
if (arabic == 6) {
result.append("VI");
} else if (arabic == 5) {
result.append("V");
} else if (arabic == 4) {
result.append("IV");
} else {
for (int i = 0; i < arabic; i++) {
result.append("I");
}
}
return result.toString();
}
Hmm, uglier still, but at least some duplication is now becoming visible: VI is V followed by I, and we already have code to append those. So we could first add the V and then rely on the for loop to add the I:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
if (remaining >= 5) {
result.append("V");
remaining -= 5;
}
if (remaining == 4) {
result.append("IV");
remaining -= 4;
}
for (int i = 0; i < remaining; i++) {
result.append("I");
}
return result.toString();
}
Still not very clean, but better than before. And we can now also handle 7 and 8. So let’s move on to 9:
@Test
public void nineIsXPrefixedByI() {
Assert.assertEquals("9", "IX", RomanNumerals.arabicToRoman(9));
}
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
if (remaining == 9) {
result.append("IX");
remaining -= 9;
}
if (remaining >= 5) {
result.append("V");
remaining -= 5;
}
if (remaining == 4) {
result.append("IV");
remaining -= 4;
}
for (int i = 0; i < remaining; i++) {
result.append("I");
}
return result.toString();
}
There’s definitely a pattern emerging. Two ifs use ==, and one uses >=, but the rest of the statements is the same. We can make them all completely identical by a slight generalization:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
if (remaining >= 9) {
result.append("IX");
remaining -= 9;
}
if (remaining >= 5) {
result.append("V");
remaining -= 5;
}
if (remaining >= 4) {
result.append("IV");
remaining -= 4;
}
for (int i = 0; i < remaining; i++) {
result.append("I");
}
return result.toString();
}
Now we can extract the duplication:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
remaining = appendRomanNumerals(remaining, 9, "IX", result);
remaining = appendRomanNumerals(remaining, 5, "V", result);
remaining = appendRomanNumerals(remaining, 4, "IV", result);
for (int i = 0; i < remaining; i++) {
result.append("I");
}
return result.toString();
}
private static int appendRomanNumerals(int arabic, int value, String romanDigits, StringBuilder builder) {
int result = arabic;
if (result >= value) {
builder.append(romanDigits);
result -= value;
}
return result;
}
There is still duplication is the enumeration of calls to appendRomanNumerals. We can turn that into a loop:
private static final int[] VALUES = { 9, 5, 4 };
private static final String[] SYMBOLS = { "IX", "V", "IV" };
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
for (int i = 0; i < VALUES.length; i++) {
remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
}
for (int i = 0; i < remaining; i++) {
result.append("I");
}
return result.toString();
}
Now that we look at the code this way, it seems that the for loop does something similar to what appendRomanNumerals does. The only difference is that the loop does it multiple times, while the method does it only once. We can generalize the method and rewrite the loop to make this duplication more visible:
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
for (int i = 0; i < VALUES.length; i++) {
remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
}
while (remaining >= 1) {
result.append("I");
remaining -= 1;
}
return result.toString();
}
private static int appendRomanNumerals(int arabic, int value, String romanDigits, StringBuilder builder) {
int result = arabic;
while (result >= value) {
builder.append(romanDigits);
result -= value;
}
return result;
}
This makes it trivial to eliminate it:
private static final int[] VALUES = { 9, 5, 4, 1 };
private static final String[] SYMBOLS = { "IX", "V", "IV", "I" };
public static String arabicToRoman(int arabic) {
StringBuilder result = new StringBuilder();
int remaining = arabic;
for (int i = 0; i < VALUES.length; i++) {
remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
}
return result.toString();
}
Now we have discovered our algorithm and new cases can be handled by just adding to the arrays:
There is still some duplication in the arrays, but one can wonder whether eliminating it would actually improve the code, so we’re just going to leave it as it is. And then there is some duplication in the fact that we have two arrays with corresponding elements. Moving to one array would necessitate the introduction of a new class to hold the value/symbol combination and I don’t think that that’s worth it.
So that concludes our tour of TDD using the Roman Numerals kata. What I really like about this kata is that it is very focused. There is hardly any API design, so coming up with tests is really easy. And the solution isn’t all that complicated either; you only need if and while. This kata really helps you hone your skills of detecting and eliminating duplication, which is a fundamental skill to have when evolving your designs.
Have fun practicing!
Update: Here is a screencast of a better version of the kata:
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:
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.
Less than three weeks till XML Amsterdam 2011 where I’ll be speaking on XACML.
XML Amsterdam is a small, focused conference dedicated to XML. As part of X-HiveEMC’s XML R&D center, I live and breathe XML, so I’m glad to have an XML conference in the Netherlands. The conference is small, so we won’t get lost in the crowd and the chances of good networking opportunities are high. And it is completely focused on XML, unlike Momentum, for instance. Finally, with speakers from all major native XML databases (xDB, MarkLogic, and eXists), we can expect some lively discussions 😉 . Especially with EMC IIG Chief Architect Jeroen van Rotterdam opening the conference with a keynote titled Is XML dead?
My presentation will introduce eXtensible Access Control Markup Language (XACML), an XML language for access control. I will place XACML in the context of access control models, and show that XACML is a future-proof technology that organizations can start using now, and then stay with as their access control needs evolve. I will continue to explain the architecture, request/response protocol, and policy language that make up XACML.
Often, when people talk about dividing a software system up into layers, they mention that you should start with the domain model. Note the word the, suggesting there is only ever a single domain model.
Not so with Command-Query Responsibility Separation (CQRS, see also CQRS Clarified). This is a pattern where the domain is described by more than one model. Updating of information happens by executing commands on one (or more) models. Viewing of information happens by querying one (or more) other models. The command and query models obviously need to be synchronized.
To see the value in such a separation, let’s consider an example. The eXtensible Access Control Markup Language (XACML) defines an XML language for expressing access control policies, and an architecture for evaluating access requests. The architecture defines different components that play different roles. The most important for the current example are the Policy Administration Point (PAP) that maintains access control policies, and the Policy Decision Point (PDP) that evaluates access requests.
Both the PAP and the PDP work with the same access control policies, but their relationship with these policies is quite different. The PAP should be able to edit and import policies, and must, therefore, understand the canonical XML format of XACML. The PDP, however, should respond as quickly as possible and XML may not be the best format to achieve that. By letting the PDP (query) work with a different model than the PAP (command), an XACML imlementation can perform best on both fronts.
What is XACML?
In short, XACML offers an architecture for access control, a policy language for describing and evaluating access control policies, and a protocol for requesting access. I’ve written about XACML in a series on EMC’s Developers Network:
What’s new in 3.0? Axiomatics were the first company to implement 3.0 (their CTO, Erik Rissanen, is editor of the spec). They’ve also summarized what has changed since 2.0, the current OASIS standard:
Who’s using XACML?
Obviously not many people are using 3.0, since it’s not a standard yet. But 2.0 has been around since 2005 and is used in various places. Below is a sample of places where XACML is being used:
You must be logged in to post a comment.