For this editorial I am returning to a topic that I have often written about in these pages: digital identity. It is a topic of fundamental importance to the future of the Internet, but one that the mainstream computing press rarely tackles directly. I am currently securing an online application, and being lazy (in a good way in this case) I am trying to reuse as much existing code as possible. As there are many enterprise and Internet application developers in the Overload audience I thought my exploration into this area would be of general interest.
By securing an application I mean that only the right people can perform the right actions against the right things, without being observed. Let's use the application I'm working on as an example. It's a simple clientserver document storage service that could be deployed within an enterprise, as part of a website implementation, or as a service on the Internet in its own right. The client connects over a TCP/IP connection and performs operations to manipulate the stored documents. The service must only be available to the users authorized by the system administrator, and each user can read and write their own documents, but can only read documents they don't own.
Let us break the security problem down into subproblems and discuss each and its possible solutions in turn.
Identity is hard to define, but for our discussion let us say that an identity is a name within a namespace, and an associated set of attributes. The name identifies the identity, and the attributes provide us with information about the identity. When we refer to an identity we use the name of the identity.
My example application could maintain its own list of users, each of whom is assigned a username. But then each user is going to have to remember yet another username, and the administrators have yet another identity namespace to manage. A more sophisticated approach would be to reuse an existing identity management service, such as the Unix password file through the Unix API, or Unix Yellow Pages/NIS/NIS+, or a directory server over LDAP [ LDAP ].
Authentication is the process by which we prove we are who we say we are. This is done by offering up credentials that can be verified against the attributes of the identity. My example application could request both a username and a password. The username is the name of the identity, and the password is the credential than can be checked against the password stored as an attribute of the identity. But, this is yet another password for the user to remember, so it'd be better to reuse an existing authentication mechanism. We can use one of the above identity management interfaces to perform the password test for us.
After a client has authenticated it performs some actions against the application, each of which must be authorized. Authorization is the process of deciding whether a client is permitted to perform the action it is attempting. My example application currently allows anyone to perform any action to any document, in other words there is no access control. Fundamentally there is a three dimensional Boolean array with the axes being: identity, action, and document. Obviously an array this size is impossible for an administrator to manage, so a more manageable representation must be used. The Unix solution is to break the identity axis down into user, system, and group, and to limit the actions to read, write, and execute, and then to have these permissions associated with each file in the file system. This isn't expressive enough, or granular enough for most applications. Directory servers on the other hand usually have very rich and expressive access control languages. Each identity is modeled as an entry, actions are usually modeled as attributes, and resources are usually modeled as entries. Other directory features such as groups, roles, and its hierarchical nature can be used to reduce the number of access control lists, and their complexity.
When an application is deployed on a public network, within a website, or even within an enterprise, we may need to ensure that snooping of the network traffic is fruitless. The solution is to secure the network channel using cryptography, in the form of SSL/TLS [ TLS ]. (The latest version of the Secure Sockets Layer specification has been named the Transport Layer Security 1.0 specification.)
So far we have come to the conclusion that my sample application can be secured by using SSL/TLS for confidentiality and by using a directory server for identity management, authentication, and authorization. Conveniently, high quality open source implementations of both are available in OpenSSL [ OpenSSL ] and OpenLDAP [ OpenLDAP ].
This solution might normally be sufficient for most applications, but I want to consider this set of problems further.
Password based systems are vulnerable to social issues. Users select poor passwords, share them with their friends, and tape them inside their desk drawer. A password policy is therefore required for enforcing good password selection. Directory services do support password policies, but they have no standard way of defining them. Other, more secure, authentication mechanisms could be used instead, such as public key cryptography, but implementing them is challenging.
My example application is currently behaving as an authentication proxy. The client presents the username and password to the server and the server passes them on to the directory server for authentication. When using more sophisticated authentication mechanisms the server is unable to proxy the authentication. The server must either perform the authentication itself, or the client must authenticate directly with the directory server and provide the server with some evidence that this authentication was successful.
Unfortunately LDAP does not provide a mechanism for the directory server to provide a token to the client so that it can prove to a third party that it has successfully authenticated. This leaves us with implementing authentication within the server application itself. Fortunately there is a standard framework defined for authentication mechanisms, called the Simple Authentication and Security Layer, or SASL [ SASL ]. SASL provides a framework for authentication mechanisms, so an application protocol need only support the framework in order to support all the authentication mechanisms that have been defined for SASL. Both the LDAP and IMAP protocol specifications defer to SASL for authentication, which suggests that the specification is of a high quality. Also, there is an open source implementation of SASL available from Carnegie Mellon University called Cyrus SASL [ CyrusSASL ].
Although SASL provides many standard authentication mechanisms developers still have to design their application protocols to carry the authentication messages back and forth. Every Internet protocol has a verb for the client to authenticate itself with the server, and they are all different. HTTP, POP, LDAP, IMAP, and FTP, amongst others, all have their own verbs for authenticating to the server. Couldn't this commonality have been factored out and pushed down the network stack so that all application protocols, whether Internet standard application protocols, or homegrown application protocols, could share this functionality? This is exactly the thinking that led Marshall Rose to define BEEP [ BEEP ]. Marshall worked on many of the Internet standards for system management, messaging systems, and directory services, so knows how to design a good application protocol. BEEP provides a framework upon which an application protocol can be defined. HTTP is commonly being used in this way right now, but it offers very little, other than not being blocked by corporate firewalls. BEEP, in contrast, offers built in authentication mechanisms via SASL, framing of the application protocol verbs, multiple channels within a connection, connection confidentiality via SSL/TLS, negotiation of the confidentiality level, permits channels to be turned around, and allows TLS to be started and stopped during a connection.
So, after further consideration, we can upgrade my example application to support more sophisticated authentication mechanisms, by layering the application protocol over BEEP. Authorization has moved into the application, but we still make use of the directory server for identity management and authorization. An open source implementation of BEEP is available [ beepcore ] that incorporates both OpenSSL and Cyrus SASL.
But, something interesting is going on; a whole new generation of digital identity development is occurring within the XML standards forums. In the next issue of Overload I plan to write about the standards being defined by the W3C and OASIS for application protocols, authentication, authentication assertions, access control, and single-sign-on. Perhaps it's possible there's a simpler solution to online application security out there.