XACML In The Cloud

The eXtensible Access Control Markup Language (XACML) is the de facto standard for authorization.

The specification defines an architecture (see image on the right) that relates the different components that make up an XACML-based system.

This post explores a variation on the standard architecture that is better suitable for use in the cloud.

Authorization in the Cloud

In cloud computing, multiple tenants share the same resources that they reach over a network. The entry point into the cloud must, of course, be protected using a Policy Enforcement Point (PEP).

Since XACML implements Attribute-Based Access Control (ABAC), we can use an attribute to indicate the tenant, and use that attribute in our policies.

We could, for instance, use the following standard attribute, which is defined in the core XACML specification: urn:oasis:names:tc:xacml:1.0:subject:subject-id-qualifier.

This identifier indicates the security domain of the subject. It identifies the administrator and policy that manages the name-space in which the subject id is administered.

Using this attribute, we can target policies to the right tenant.

Keeping Policies For Different Tenants Separate

We don’t want to mix policies for different tenants.

First of all, we don’t want a change in policy for one tenant to ever be able to affect a different tenant. Keeping those policies separate is one way to ensure that can never happen.

We can achieve the same goal by keeping all policies together and carefully writing top-level policy sets. But we are better off employing the security best practice of segmentation and keeping policies for different tenants separate in case there was a problem with those top-level policies or with the Policy Decision Point (PDP) evaluating them (defense in depth).

Multi-tenant XACML Architecture

We can use the composite pattern to implement a PDP that our cloud PEP can call.

This composite PDP will extract the tenant attribute from the request, and forward the request to a tenant-specific Context Handler/PDP/PIP/PAP system based on the value of the tenant attribute.

In the figure on the right, the composite PDP is called Multi-tenant PDP. It uses a component called Tenant-PDP Provider that is responsible for looking up the correct PDP based on the tenant attribute.

Outbound Passwords

Much has been written on how to securely store passwords. This sort of advice deals with the common situation where your users present their passwords to your application in order to gain access.

But what if the roles are reversed, and your application is the one that needs to present a password to another application? For instance, your web application must authenticate with the database server before it can retrieve data.

Such credentials are called outbound passwords.

Outbound Passwords Must Be Stored Somewhere

Outbound passwords must be treated like any other password. For instance, they must be as strong as any password.

But there is one exception to the usual advice about passwords: outbound passwords must be written down somehow. You can’t expect a human to type in a password every time your web application connects to the database server.

This begs the question of how we’re supposed to write the outbound password down.

Storing Outbound Passwords In Code Is A Bad Idea

The first thing that may come to mind is to simply store the outbound password in the source code. This is a bad idea.

With access to source code, the password can easily be found using a tool like grep. But even access to binary code gives an attacker a good chance of finding the password. Tools like javap produce output that makes it easy to go through all strings. And since the password must be sufficiently strong, an attacker can just concentrate on the strings with the highest entropy and try those as passwords.

To add insult to injury, once a hard-coded password is compromised, there is no way to recover from the breach without patching the code!

Solution #1: Store Encrypted Outbound Passwords In Configuration Files

So the outbound password must be stored outside of the code, and the code must be able to read it. The most logical place then, is to store it in a configuration file.

To prevent an attacker from reading the outbound password, it must be encrypted using a strong encryption algorithm, like AES. But now we’re faced with a different version of the same problem: how does the application store the encryption key?

One option is to store the encryption key in a separate configuration file, with stricter permissions set on it. That way, most administrators will not be able to access it. This scheme is certainly not 100% safe, but at least it will keep casual attackers out.

A more secure option is to use key management services, perhaps based on the Key Management Interoperability Protocol (KMIP).

In this case, the encryption key is not stored with the application, but in a separate key store. KMIP also supports revoking keys in case of a breach.

Solution #2: Provide Outbound Passwords During Start Up

An even more secure solution is to only store the outbound password in memory. This requires that administrators provide the password when the application starts up.

You can even go a step further and use a split-key approach, where multiple administrators each provide part of a key, while nobody knows the whole key. This approach is promoted in the PCI DSS standard.

Providing keys at start up may be more secure than storing the encryption key in a configuration file, but it has a big drawback: it prevents automatic restarts. The fact that humans are involved at all makes this approach impractical in a cloud environment.

Creating Outbound Passwords

If your application has some control over the external system that it needs to connect to, it may be able to determine the outbound password, just like your users define their passwords for your application.

For instance, in a multi-tenant environment, data for the tenants might be stored in separate databases, and your application may be able to pick an outbound password for each one of those as it creates them.

Created outbound passwords must be sufficiently strong. One way to accomplish that is to use random strings, with characters from different character classes. Another approach is Diceware.

Make sure to use a good random number generator. In Java, for example, prefer SecureRandom over plain old Random.