Tuesday, January 22, 2013

SOA and Security

We have talked about WCF at great length, but have focused mainly on the scalability and dependability of the Service-Oriented Architecture (SOA) itself.  One of the topics we haven't gotten into at a sufficient depth is security and service access management as an integral part of the SOA design.  I'd like to explore some of the options available for securing your services while adhering to the good design principles of SOA.  But first, I would like to discuss what it means to have security built in to your SOA.  We know that a well-designed SOA should be an architecture of loosely coupled components that can be distributed across platform, technology, and physical environments. Service components can be abstracted, grouped and presented to provide a single process, or to provide more complex user stories for a consuming application. Services are the preferred communication technique across application boundaries, including platform, deployment, and trust boundaries.  The key attributes of SOA are:
  • Interoperable. Components can be interoperable across platform and technology boundaries.  In fact, a well designed service should be totally agnostic to the technologies interacting with it.
  • Autonomous. Services are exposed as autonomous components that can be versioned and managed independently.  As with all good platform design, think of each service as a black box.
  • Abstracted. Services should be abstracted at a granular enough level so they can be grouped by another service or application to perform more complex operations as a single method.  This is what I often call a user story service layer.  Business logic can be abstracted and presented as specific component-like stories for targeted consumption.
  • Interface based. Interfaces are defined by message contracts and schemas. Operation calls and parameters are passed in XML message envelopes.  Stick to agreed upon standards here for maximum scalability and interoperability.
  • Location agnostic. Service components can be consumed from the same machine or distributed to remote machines. The service interface and logic is independent of the transport and protocol used to access the service.  This gives you many points to scale and inject redundancy for performance and dependability.
  • Discoverable. Services publish their interface in such a way that client applications can discover them and generate a proxy mechanism for consumption.

I try to adhere to the agreed upon four tenets of SOA from Microsoft architect Don Box:
  • Boundaries are explicit. Services are black-boxed and will never allow direct internal visibility.  All interaction comes from agreed upon messaging and interaction methods.
  • Services are autonomous. Each service is viewed autonomously with a complete disregard for any client activities or accompanying services.  While interaction is allowed and obviously required, see the first tenet.  These services should not be intimately aware of each other.
  • Services share schemas and contracts, not class. Services share contracts and schemas to communicate.  This is analogous to a menu in a restaurant.  All of the inner workings are abstracted to a set of choices and communicated with an agreed upon contract. 
  • Compatibility is based upon policy. Policy in this case means definition of transport, protocol, security, etc.  This is primarily where we are focusing today.
To focus in on the compatibility tenet, let's delve into security at a deeper level. Security is fundamentally about protecting assets. Assets may be physical items such as code sets, methods or a database, but also can be more nebulous, such as your brand.  It is important to recognize that security is a commitment, not a software feature, as it is a never-ending process. As you design services and applications, you need to identify potential threats and understand that each threat presents a degree of risk. Security is basically about mitigating those risks via restrictions and/or counter measures. When done effectively,  security is a combination of people, process, and technology.

Security is comprised primarily of the following ideals:
  • Authentication. Authentication is, at its base, the ability for a system to know who the user is.  It is the process of uniquely identifying the users of applications and services. Keep in mind that users of applications and services may be people, other services, processes, or computers. When reading security documentation or writing code, these 'users' are called Principles.
  • Authorization. Authorization is the equivalent of a key card.  Just as a key card gives its holder permission to enter certain rooms in a building, authorization manages the resources and operations that the authenticated client is permitted to access. These resources can include operations, physical storage (as granular as tables and rows), registry keys and other  configuration data. Operations are basically equivalent to the methods at any given layer of the SOA.
  • Auditing. Effective auditing and logging is the key to non-repudiation. Non-repudiation at its base is evidence.  If you have implementing effective auditing, a user or process will be unable to deny its activities. For example, in a medical system, auditing is required to make sure that a user cannot deny changing information in a specific patient chart.
  • Confidentiality. Confidentiality, or privacy, is the process of making sure that all data is private and confidential and cannot be viewed by unauthorized users who attempt to monitor the traffic across a network. Encryption is the most used method of confidentiality.  Primarily, you must ensure that the only users and processes who can view specific data, are the ones for whom it is intended.
  • Integrity. Integrity is the guarantee that data is protected from modification, be it accidental or malicious. Like privacy, integrity is a huge deal, particularly when there is sensitive data being passed across networks. Integrity for data in transit is typically provided by using hashing and message authentication codes.
  • Availability. From a security perspective, availability means that systems remain available for legitimate users.  There are some malicious individuals who will attempt to bring down your services and thus cause your real users to be unable to leverage the system.  The denial of service attack (DoS) is aimed at simply over-running your system and bringing it down. 
Some keys to building secure services include the following:
  • Identify the targets for security. You should think through all of the objectives you have for security. User stories are a good tool for gaining insight into the natural roles and levels of security that come from usage of your system.  Identify all assets that need security as well as the granularity to which security is applied.
  • Understand the possible threats. Try to identify the threats which are relevant for your scenarios and context. This is called 'Threat Modeling' and is a good practice which helps you identify the realistic  threats to your system. Your security targets will help you prioritize your threats and vulnerabilities. Using the threat model, architects and developers should address vulnerabilities, and QA should ensure that the developers have addressed the vulnerability.
  • Stay away from 'roll your own' security. Proven principles, patterns, and practices are the best place to start building a security model.  By using time-tested, proven principles, patterns, and practices, you can eliminate entire groups of security problems without needing to discover the specific vulnerability in your identification process. You should take advantage of the experience of others when it comes to security.  That being said, proven principles, patterns, and practices are a great starting point.  But like all other architectural paradigms, security is fact dependent and you should not just implement something off-the-shelf without going through the identification and threat processes.
  • Commit to security as an eternal process.  Security should be of paramount consideration at every stage of a service, application or software development life cycle. At every stage, targets should be defined, threats should be modeled and mitigating actions should be taken.  Security is not and will never be a 'set it and forget it' item.
I am going to dig deeper into some of the possible mechanisms for securing WCF services in a web environment in the near future.  As part of a current project, I am spending a lot of mental energy looking into the options.  I will post some of the opportunities and how to leverage them in the coming days and weeks.