Chapter 9. Codifying security policies

This chapter covers

  • WS-Policy
  • WS-MetadataExchange and WS-PolicyAttachment
  • WS-Security Policy

In the previous chapter, which marked the beginning of part III, we began exploring how we can create an enterprise-class SOA security solution using the lessons from part II. As a first step, we looked at how to implement a shared security service that reduces the security enforcement burden on endpoints. That solution addresses only some of the challenges in enterprise security. We will address the remaining ones in this chapter and the next. In this chapter, we will focus on three challenges that can be addressed by adopting a declarative approach to security:

  1. Ease of development and administration There’s just too much detail that every service developer and security administrator needs to know in order to effectively secure services. Unless the security framework is easy to use for the developers and administrators, it cannot be successful.
  2. Consistency of security checks Most enterprises will end up having more than one security service for administrative or historical reasons. When a merger happens between two enterprises, each one’s security service may remain operational side-by-side. Furthermore, there may be some endpoints into which security is hard-wired. The challenge in such enterprises is to create and maintain a consistent set of security checks across all the security enforcement points.
  3. Interoperability of security solutions Security solutions in an enterprise will have to interoperate with the security solutions of the enterprise’s customers, suppliers, and partners. Interoperability is not guaranteed even if all the security solutions are 100% standards-compliant. This is because standards allow administrators to make a lot of choices—a security solution in an enterprise may demand 512-bit encryption keys whereas a partner’s security solution may only be able to work with 128-bit encryption keys. Obviously interoperability is a concern.

This chapter introduces the concept of declarative security in SOA and shows how you can address these three challenges using security policies in web services. By the end of this chapter, you will understand how to codify and share security policies using standards such as WS-Policy, WS-SecurityPolicy, WS-PolicyAttachment, and WS-MetadataExchange. As some of these standards are not easy to understand, we use examples as the primary mechanism to describe the ideas behind them. You will also learn the shortcomings of these standards and be able to plan for necessary extensions in your use.

We will start off by explaining the declarative approach and why it makes sense for SOA security solutions.

9.1. Introducing declarative security

Complexity in programming has been growing over the years. Gone are the days when people armed with the knowledge of a language and a few libraries develop complete applications. These days, developers have to be familiar with several different technologies, standards, and best practices to be effective at their jobs. To complicate matters further, most of the developmental activities that programmers do these days require intricate domain knowledge. Typically, developers do not have this knowledge and need to work with domain experts to develop the solution. Domain expertise is needed in more than the application field. Security, corporate governance, and graphic design are also examples of domains that require specialized expertise.

To help developers and domain experts collaborate without having to fully understand each other’s work, most development platforms these days try to separate out concerns. Declarative programming is one mechanism that’s often used to separate a concern from the rest of the solution.

Declarative programming takes many shapes. In web application development, a graphic artist can declare the look and feel of various elements in the application using Cascading Style Sheets (CSS). The web application developer simply refers to CSS files produced by the graphic artist to get the right look and feel for each of the elements in the application.

A more complex example would be if we let domain experts declare the rules of the system. Taxation domain expert may codify taxation rules by supplying statements such as “long-term gains on energy stocks are tax-exempt for the year 2006.” The declarations are not written in such clear English, but nevertheless, they are separate from the program and available for a domain expert to view, validate, modify, and maintain.

SOA too has several different experts collaborating to develop a solution. In particular, in SOA security, security policies can be developed by people who understand security issues well. If we are to secure services by writing code the way we did in the examples in part II, developers and security experts will have to work very closely with each other. This is clearly not a scalable approach.

Does the idea of security as a service, introduced in the previous chapter, solve this problem? No. Even with a shared security service, developers of each service still need to write the code for interacting with the security service and using its findings appropriately. Instead, if the SOA platforms on which services are hosted allow security experts to declaratively specify the security policies that should be enforced, developers need not work closely with the security experts. Developers can develop services and security experts can set up security policies that should be enforced—the work of both communities will come together seamlessly.

Most web services platforms already support separation of concerns between security experts and service developers. In fact, the latest versions of all leading web services platforms take a policy-driven approach to security, making declarative security not only possible but also the easiest and the most natural way to secure services. If you are developing a service today, you can configure it to be secured by a security policy that was created independently. The security policy may be created by security experts in your enterprises, or you may pick one of the prepackaged security policies provided by your platform vendor. In either case, you are taking a declarative approach to security.

Declarative security can be adapted to varying degrees. The benefits and the complexity involved will differ accordingly. Here are three different degrees to which you can employ declarative security:

  1. Internal use within an enterprise to ensure consistent application of security policies by all security solutions used by the enterprise
  2. Use at design time to ensure interoperability between the enterprise’s security solutions and those of partners/customers
  3. Use at runtime to ensure interoperability between the enterprise’s security solutions and those of partners/customers

Let us look deeper into each of these use cases, in that order.

9.1.1. Policy consolidation for planning and consistent enforcement

Declarative security can be employed internally within an enterprise to ensure that security policies are applied consistently by all security solutions used by the enterprise. An analogy will help you understand this better. If you programmed in the C language, you will remember how you can group the definitions of related constants as a header file and include them in multiple applications using the #include mechanism. This mechanism makes it easy to consolidate and manage constants that should have consistent values across multiple applications. It has no bearing on the execution of the code; its use is mainly for maintenance.

Similarly, declarative security can be used to codify and consolidate the security policies in use within an enterprise. Even if we don’t use the policies at runtime, this step of codifying and consolidating all the security policies is still useful. In OO modeling, describing the model in a suitable language can help developers understand a problem and make it tractable. Similarly, codified and consolidated security policies are primarily of help in planning and development.

A full description of the process for policy codification and consolidation is beyond the scope of this book. To describe this process briefly, it starts with a cataloguing of the existing services. After that, the security policy of each service needs to be described. The security policies of each service may subsequently have to be evaluated for compliance with government regulations and corporate governance policies. Eventually, the policies for all services are codified and consolidated in a repository. The codification can take place in several different ways, depending on the tools used.

As shown in figure 9.1, security policies are often scattered in compiled forms in different solutions. Converting security policies into declarative statements (that is, codifying security policies) and consolidating them in a repository will help with consistent application of policies across all solutions in an enterprise. As mentioned earlier, creating and managing a policy repository can be the responsibility of a security expert or experts group. It is the responsibility of the developers to make sure that the applications implement these policies.

Figure 9.1. Developers today are forced to hard-code security policies into each solution. The vision of declarative security is to allow a security expert to create an enterprise-wide policy repository that each solution in the enterprise can refer to.

The developers, without any special tools or frameworks, can read the codified policies for the services and turn them into working code. This is very much like developing code from use cases. If the security policy of an enterprise states that all uses of HTTPS should be with 1024-bit encryption the developer makes sure that his application follows that rule.

This approach clearly is error-prone and tedious. While it still achieves consistency of security checks, it is not easy to develop; in addition, it does not ensure interoperability. If the tools and frameworks support the development process to use codified policies automatically, as shown in figure 9.1, it can make development a lot easier.

To fully realize the potential of declarative security, we need a few standards.

  • The language for codifying policies should be a standard. A standard language will help us in creating design-time tools that can read the security policy for a service and generate code or configuration files to implement the policy. It will also help us in creating runtime platforms that can read the security policy for a service and enforce it.
  • The protocol to fetch security policy from the policy repository should be standard. A runtime platform that can understand security policies and enforce them can use such a standard to fetch the applicable policy from the repository.

The benefits of these standards are ease of use and interoperability. Let’s see how to derive these benefits in the next two subsections.

9.1.2. Use at design time to ensure interoperability

Declarative security can be used at design/deployment time to ensure interoperability between the enterprise’s security solutions and those of partners/customers. The developer of a service consumer can fetch the security policies of the service provider and his own enterprise, reconcile the differences, and develop the consumer to comply with both policies. Better yet, he can do this using a design-time tool. Recall that we did something similar in chapter 2. We generated a service consumer stub from a description of the service in WSDL. Similarly, a tool can assist the developer in complying with the security policies of all parties involved.

For example, as shown in figure 9.2, when the developer is using his application designer, it may present a choice of authentication mechanisms that are supported by the policies of both parties. The developer may opt for one possibility. Based on that choice, the tool can generate the code required for authentication.

Figure 9.2. A design-time tool can obtain and compare the security policies of both parties, present options that are compatible with both policies, and generate code based on user choices.

The idea of using security policy declarations at design time to ensure interoperability is simple and therefore attractive. It is not always practical. The security policies of the service provider and/or the service consumer are liable to change over time. In such cases, the solutions on both sides may have to be rebuilt when the policy changes on one side. A runtime mechanism to ensure interoperability will not suffer from this problem. Let’s look at that possibility next.

9.1.3. Use at runtime to ensure interoperability

So far, we’ve looked at two different ways to use declarative security: consolidate existing policies and validate them, or use at design time to generate code and configuration. We will look at a more advanced way of using declarative security—namely, using it at runtime.

Consider how your browser interacts with SSL-enabled web servers. Each web server may support several different encryption algorithms with different key strengths. Your browser is also capable of communicating at different encryption strengths. Somehow they negotiate the best possible security mechanism to communicate between themselves. Similarly, a service and a service consumer can exchange security policies at runtime and figure out how to interoperate.

The level of sophistication required in this scenario is clearly much higher. It requires security frameworks that can fetch and reconcile the security policies of parties involved in a message exchange, and customize themselves at runtime. Figure 9.3 shows the requirement.

Figure 9.3. Use of security policies at runtime to achieve interoperability between any two parties.

As figure 9.3 shows, the policies of parties involved in the message exchange can be fetched and reconciled at runtime to ensure interoperability. While the sophistication required for this in practice is quite high, the benefits of interoperability are attractive enough to justify the effort.

Let’s summarize what you have learned in this section so far. Current-generation SOA platforms allow you to declaratively specify the security requirements of a service. This approach is preferable over coding-in the security requirements into each service because:

  1. It helps us hide the complexity of all the technologies that go into SOA security from service developers and administrators. Security experts can independently formulate the security policies that the SOA platforms will enforce.
  2. The security policies of the enterprise can be stored and managed centrally, ensuring consistency of security checks made by different solutions in the enterprise.
  3. Codified security policies can be used to figure out how security solutions of an enterprise can interoperate with the security solutions of its partners and customers.

These three benefits can be realized in practice to varying degrees. The first benefit is the easiest to realize. Almost every leading SOA platform already supports declarative security, helping us hide the complexity of SOA security technologies from service developers and administrators.

The second benefit is a little tougher to realize. Consolidation of security policies using a central repository is easy if there is a standard language for codifying security policies. But all is not lost if there is no standard policy language. Consolidation is still possible, as tools can be created to transform policies expressed in one language into another.

The third benefit is the toughest to realize. A standard policy language is a must if we are to use policies to ensure interoperability. This is possibly why WS-Policy and WS-SecurityPolicy, which, together, define a standard policy language for use in security solutions, seem to limit themselves to addressing the needs of interoperability.

Vendors currently define their own custom extensions to WS-Policy and WS-SecurityPolicy in order to allow you to declaratively specify security for your services. As we cannot possibly describe the extensions created by all leading vendors here, we will restrict the discussion in the rest of this chapter to what the standards cater to now: interoperability.

Before we look into WS-Policy and WS-SecurityPolicy, it helps to first understand the kind of interoperability problems that we seek to solve by codifying security policies. We will dedicate the next section to discussing the interoperability challenges in SOA security.

9.2. Interoperability challenges in SOA security

One of the most compelling arguments in favor of SOA is that it lets enterprises reuse software without being inhibited by differences in platforms. Given this promise, designers of enterprise SOA security just cannot wish for a homogeneous environment. Any enterprise-class SOA security solution will have to interoperate with multiple other implementations of SOA security.

To understand the challenge of interoperability in SOA security, let’s look at the sources of incompatibility between two implementations of SOA security standards. This analysis will help us understand what kind of policy declarations are required to enhance interoperability. We will use this understanding in later sections when we talk about WS-SecurityPolicy.

9.2.1. Sources of incompatibility

Here are the main reasons why two different applications implementing the same SOA security standards may be incompatible:

  • The SOA security standards you have learned about in previous chapters leave considerable choice to implementers. Different implementations may make different choices, leading to incompatibility.
  • Most implementations do not support all possible choices enumerated by the standards in order to keep the cost of implementation low. This situation leads to possible incompatibilities between one security solution and another.

Table 9.1 goes deeper into the sources of incompatibilities. It may not be an exhaustive list, but it is representative of the incompatibility problems that can arise.

Table 9.1. Causes of incompatibility in web services security solutions

Cause for incompatibility

Description

Choice between transport-layer security and message-level security Most home-grown web services toolkits still rely on transport-layer security (HTTPS in most cases). Such implementations will clearly not be able to interoperate with endpoints that rely on message-level security enabled by WS-Security.
Third party to trust: WS-Trust STS, certificate authority, Kerberos KDC, SAML authority There will never be an agreement on a central security authority. Given this, two implementations that rely on different security authorities will find it difficult to interoperate without prior agreement on some common security authority that each party trusts directly or indirectly.
Versions of SOAP, WS-Security, security token profiles, WS-Trust, SSL/TLS, and other applicable standards As web services standards evolve, implementations will vary in support for different versions of standards. Two implementations compliant with different versions of the same standard will run into interoperability problems unless the higher version implementation is backward-compatible.
Types of supported security tokens If a service consumer cannot provide a token required by the service provider, interoperability will clearly suffer. Most home-grown service consumers still use username and password for authentication. If a service provider starts requiring the use of digital certificates for authentication, that provider’s services can no longer be accessed by service consumers who do not have the ability to use digital certificates.
Inclusion/referral of security tokens and in the case of referral, mechanisms used WS-Security leaves the choice of token transport to implementers in almost all cases. Security tokens can be embedded or referred to using one or more mechanisms. An X.509 certificate can be referred to by its issuer and serial number or by its X.509 SubjectKeyIdentifier. These choices will cause interoperability problems between implementations that do not support all possible referencing mechanisms.
Choice of algorithms, key strengths, transformations, and encoding Multiple algorithms exist for almost every cryptography related activity we use in SOA security. This choice will lead to interoperability problems, as not all implementations will support every possible algorithm with every possible variation (such as key strength).
Encryption/Signing of only selected parts in a message Most implementations still only support encryption/signatures on the entirety of message body/message. When working with such endpoints, the other endpoint cannot choose to do selective encryption and signing.
Mechanisms used to refer to protected message elements The absence of a single mechanism to identify elements in a message has already caused much damage, as we learned in previous chapters. A mix of ID/IDREF with wsu:Id, Id, and xml:id will cause a lot of interoperability problems.
Order of encryption and signing As we discussed in the chapter on signatures, we have the option to encrypt and then sign or sign and then encrypt. There are positives and negatives with both orders. Good implementations should be able to deal with both, but poor implementations that assume one order will break if the other party uses another.
Order of entries in a WS-Security header It is a little difficult to develop efficient implementations that can access the entries in the security header in random order, as and when required. Implementations may have specific requirements on the order of elements in the WS-Security header.
Use and location of timestamp in a WS-Security header Timestamps are needed for detecting replay attacks. There are two practical issues in using timestamps. First, clocks need to be synchronized closely. Second, implementations should understand time zone information. Daylight saving time (DST) is not easy to deal with, especially if different countries keep changing the dates on which DST kicks in/out.
Attachment mechanism We describe the evolution of attachment standards in appendix C. As different implementations are likely to use different standards in the near future, interoperability problems are bound to occur.

As you can see, interoperability problems can stem from different sources:

  • Difficulty in implementing choices
  • Different choices to solve the same problems
  • Evolving standards
  • Several optional components to the implementation

There are two different ways to solve these interoperability issues. As we mentioned, we can determine the subset of standards to use based on the security policies of involved parties at runtime, which is not easy to implement and unsuitable for some situations.

A simpler solution is to restrict the choices to a small subset (profile), so that implementers have a better chance of supporting that subset. It is clear that this simpler solution cannot solve the interoperability problem completely, will still have to be left to the implementors. Still, this solution is worthwhile in practice. The WS-I Basic Security Profile specification, introduced next, is a standard that attempts this incomplete but simpler solution to interoperability problems in SOA security.

9.2.2. WS-I basic security profile

The Web Services-Interoperability (WS-I) Organization is an industry consortium that seeks to enhance interoperability among web services implementations. WS-I publishes implementation guidelines known as profiles for popular web services specifications with the goal of enhancing interoperability. WS-I Basic Profile 1.0 (later split into Simple SOAP Binding Profile 1.0 and Basic Profile 1.1) provides guidelines for implementing SOAP, WSDL, and UDDI. WS-I has also published multiple working drafts of a Basic Security Profile that similarly clarifies WS-Security and associated security token profiles.

Readers of this book will find drafts of WS-I Basic Security Profile very easy to understand. We will not repeating here the long list of rules laid down by this specification. But to help you better understand the basic ideas behind WS-I Basic Security Profile, we will list the kinds of rules you will see in the profile.

  • Elimination of unnecessary choices WS-I Basic Security Profile prohibits the use of SSL 2.0, since there are known issues in SSL 2.0 that are fixed in 3.0. Implementations can assume that eliminated choices are not used and simplify the code.
  • Establishing best practices Where possible, the profile establishes best practices. WS-I Basic Security Profile prohibits the use of more than one WS-Security header with the actor attribute omitted. These best practices again make the implementations simple.
  • Making type data mandatory WS-Security does not mandate the presence of type data when different types of values can be used in a particular context. WS-I Basic Security Profile enhances interoperability by making the presence of type data mandatory in such cases. A security token reference must specify a value type.

As you can see, WS-I Basic Security Profile not only enhances interoperability but also makes it easier to develop a security solution by eliminating unnecessary choices and providing clarifications needed to eliminate the gray areas in WS-Security. WS-I Basic Security Profile, however, cannot guarantee interoperability between conforming implementations. This is because not all choice can be eliminated by WS-I Basic Security Profile. WS-I Basic Security Profile, however, cannot eliminate the choice between PKI and Kerberos. Of course, such a choice is required by implementations. This is where WS-Policy and WS-SecurityPolicy come into play. These specifications attempt to provide a comprehensive framework for ensuring interoperability among web services security implementations. We will introduce you to both of these standards in the next two sections.

9.3. Web services policy framework

As you know by now, a declarative approach to SOA security can bring three main benefits to an enterprise. It can:

  • Simplify the job of service developers/administrators
  • Bring consistency to security checks done by different security solutions in the enterprise
  • Ensure interoperability with security solutions of partners/customers

Of these three, standards are a key enabler for the last; the other two can benefit from standards too, but are not impossible to accomplish without standards. Currently (at the time of writing this book), standards for declarative security almost exclusively focus on enabling interoperability.

Interoperability of security solutions happens to be a special case of a larger problem. Just like WS-Security, other web services standards that extend SOAP such as WS-ReliableMessaging also leave a lot of choice to implementers in order to ensure applicability in a wide variety of situations. Unless there are mechanisms for ensuring interoperability, it is quite likely that web services implementations that use any of these extensions will not be compatible.

It makes sense to standardize a generic framework for ensuring interoperability. In this section, we will discuss such a framework proposed in WS-Policy and related standards. In particular, we will:

  • Formalize the concepts of policy and policy intersection
  • Illustrate WS-Policy with an example
  • Describe WS-MetadataExchange and WS-PolicyAttachment, two standards that specify how policies may be fetched

In section 9.4, we’ll look at applying this framework specifically to create security policies. Let’s start with a discussion of the formal concepts of policy and policy intersection.

9.3.1. What is a policy?

The word policy suggests process-related rules and guidelines. The definition of a policy is more formal in the context of web services. In this context, a policy is a machine-readable expression of what is required in a message exchange from a WS-Standards perspective. To understand the motivation behind this formalism, let’s look at an example.

Figure 9.4 shows the use of policies for ensuring interoperability in a two-party scenario. In this scenario, party 1 needs to make a web services call to party 2. It does not know the requirements, capabilities, and constraints of party 2. In step 1 of figure 9.4, party 1 fetches the policy of party 2. Party 2’s policy tells party 1 how to customize its implementation in order to interoperate with party 2. Party 2 may have the requirement that all parties invoking its services should:

  • Sign the body of the request.
  • Encrypt the body of the request.
  • Encrypt the signature of the body.
  • Include a timestamp as the last entry in WS-Security header.
Figure 9.4. Policy-based approach to ensuring interoperability between two parties in a web service message exchange

In addition, it may also have limitations on the algorithms and key strengths it can use for decryption and verifying signatures. Party 2 may only support AES with 128/192-bit keys for decryption.

Party 1 can understand these requirements and constraints by fetching the security policy of party 2. Naturally, it may also have its own requirements and limitations. Party 1’s security solution may have its own list of supported algorithms and key strengths that can be used in encryption and signatures. In our example, let’s assume that party 1 can encrypt using AES and 192/256-bit keys.

At this point, it is obvious to us that party 1 can only use AES with 192-bit keys for encryption when communicating with party 2. The question is: Can machines make this analysis as well and ensure interoperability?

In the simple scenario illustrated in figure 9.5, party 1 needs to compare its own list of supported algorithms and key strengths with the list provided in party 2’s policy and see if the two lists have any common elements. If they do, the two policies are said to intersect or be compatible. Party 1 can customize its call to party 2 using the effective policy determined by computing the intersection between the two policies.

Figure 9.5. Illustration of a policy intersection. Party 1’s policy states that party 1 can only do encryption using AES with 192/256-bit keys. Party 2’s policy states that it can only decrypt text encrypted using AES with 128/192-bit keys. The intersection of the two policies dictates that both parties use AES with 192-bit keys if they are to interoperate.

Steps 2 and 3 of figure 9.4 illustrate this process. Party 1 fetches its local policy, compares it with the policy of party 2, and determines an effective policy by computing the intersection between the two policies.

Once an effective policy is computed, party 1 makes the web service call to party 2 using the guidelines in the effective policy. This is shown as step 4 in figure 9.4.

The same mechanism can be used in the opposite direction as well. Party 2 can fetch party 1’s policy when receiving responses, compute the intersection between its own capabilities and party 1’s requirements/constraints, and customize the way it responds to party 1’s request.

Comparing two policies, computing their intersection, and customizing a web service on the fly to ensure interoperability is a complex task. Most web services toolkits are not capable of doing this yet. For now, polices need to be used offline to evaluate interoperability between service providers and consumers and to customize producers and consumers at development or deployment time.

Now that you understand the formal definitions of policy and policy intersections, we can introduce you to WS-Policy. We do that next with the help of an example.

9.3.2. WS-Policy

The WS-Policy specification provides the basic syntax for expressing policies. Listing 9.1 is an example policy that lays down the text encoding and languages supported by the subject of the policy.

Listing 9.1. Makeup of a WS-Policy

As you can see from this example, a policy consists of one or more policy assertions that can be grouped together as policy alternatives. In this example, there are two policy alternatives. The first requires the use of a language named Telugu (indicated by the language identifier te) with UTF-8 as the encoding. The second requires the use of English with ISO-8859-1 encoding.

Putting it all together, here’s what this policy is saying: The service/service consumer that is the subject of this policy can understand UTF-8–encoded Telugu messages or ISO-8859-1–encoded English messages.

WS-Policy limits itself to providing the syntax for writing up policies as collections of policy alternatives, each alternative being a collection of policy assertions. It rightly does not go on to enumerate all possible assertions that can be used in a policy. Instead, WS-Policy leaves it up to other specifications to come up with the list of policy assertions that make sense in each domain. The wsp: Language and wsp:TextEncoding assertions shown in listing 9.1, along with a few other very basic assertions useful for all web services, are standardized by a specification named WS-PolicyAssertions and not WS-Policy. In the security domain, WS-SecurityPolicy specifies the list of assertions that can be used for making security policy assertions.

WS-Policy also specifies an algorithm to compare two policies without understanding the semantics of assertions used in either policy and compute their intersection to a first approximation. We will not discuss the algorithm here. You do not need the details of this algorithm unless:

  1. You are developing a policy engine that needs to compare policies and compute intersections.
  2. You are creating custom policy assertions for your domain and want to make sure that the approximation made by WS-Policy’s algorithm does not lead to incorrect comparison of your custom assertions.

If you fall into either of these categories, you should refer to the WS-Policy specification itself, which provides you with complete details of the policy specification.

In summary, here’s what WS-Policy provides:

  • A syntax for expressing the alternatives a service/service consumer supports, where each alternative is a collection of assertions that must hold true
  • An algorithm for comparing two policies and computing their intersection to a first approximation, even without understanding what the two policies are saying

Did you notice that there is one missing piece in the standards-based solution we have discussed so far for the interoperability puzzle? Let’s say you are a service consumer. If you can access the service provider’s policy and your own policy, you can use the policy intersection algorithm specified by WS-Policy to compute the effective policy. But how do you access the service provider’s policy? This is the topic of the next section.

9.3.3. Standards for fetching policy: WS-MetadataExchange and WS-PolicyAttachment

The generic policy framework we are describing in this chapter seeks to standardize the approach for solving the interoperability puzzle in web services. As we just pointed out, one of the important questions that the framework should help answer is: How does one fetch the policies of a party one wants to communicate with? Figure 9.6 shows three possible answers to this question.

  1. You can make a request to the other party’s metadata service.
  2. If you are a service consumer, you can fetch the WSDL of the target service and look for the policies attached to service, endpoint, operation, and message definitions.
  3. You can discover the policies of the other party via UDDI.
Figure 9.6. Different ways of fetching a policy: query via WS-MetadataExchange or look up policies attached to WSDL/UDDI entities as described in WS-PolicyAttachment.

The first of these possibilities is standardized by WS-MetadataExchange. The second and third possibilities are described by WS-PolicyAttachment. Let us look at both of these standards next, starting with WS-MetadataExchange.

WS-MetadataExchange

WS-MetadataExchange defines a very simple protocol for querying metadata such as XSD, WSDL, and WS-Policy. Figure 9.7 depicts how a policy document can be fetched using WS-MetadataExchange.

Figure 9.7. WS-MetadataExchange provides a simple protocol to fetch metadata such as XSD, WSDL, and WS-Policy. The Dialect element in the GetMetaData request is used to indicate what type of metadata is being requested. To fetch a WS-Policy document, the Dialect element can be set to a URI that identifies WS-Policy as the type of requested metadata.

As the figure shows, any entity seeking to fetch metadata can use the GetMetaData request defined by WS-MetadataExchange. The Dialect element in the request can be used to indicate what type of metadata is being requested. Listing 9.2 shows an example request in which the Dialect element is set to a URI that identifies the metadata being requested as a WS-Policy document.

Listing 9.2. Sample GetMetaData request

In this example, the client is requesting for the policy from the server. The server may respond with the response shown in listing 9.3.

Listing 9.3. Sample response to a GetMetadata requests

WS-MetadataExchange is that simple to use. Observe that WS-MetadataExchange does not assume a policy repository (or registry) that is shared by the service provider and service consumer. Policies can be exchanged by any two parties using this protocol.

Service consumers often have access to a service registry in which service descriptions (WSDL documents) are stored. In such cases, it is possible to eliminate the need for a metadata service by attaching policies to service descriptions. The WS-PolicyAttachment standard specifies how this can be done. We will describe WS-PolicyAttachment next.

WS-PolicyAttachment

WS-PolicyAttachment defines how policies can be attached to WSDL definitions and UDDI entities. We will restrict the discussion here to attaching policies to WSDL, since we have not discussed UDDI in detail in this book.

WS-PolicyAttachment identifies four levels at which policies can be defined for a web service. These are Service, Endpoint, Operation, and Message. Formally, these are referred to as policy subjects, as they are the subjects of policy assertions. For example:

1.  At the service level, a policy might indicate that all message exchanges need to be logged for auditing purposes.

2.  At the endpoint level, a policy might indicate that a particular set of algorithms and key strengths are supported for encryption and signatures.

3.  At the operation level, a policy might indicate that a SAML assertion is needed to indicate the privileges and/or preferences of the caller.

4.  At the message level, a policy might identify parts of the message that need to be protected with encryption and/or signatures.

The policy to use in a message exchange is a combination of those associated with each of these four levels or subjects. Syntactically, the policy is split into these four portions in WSDL. WS-PolicyAttachment identifies multiple points in WSDL where a policy can be attached for each of these subjects. The endpoint is the subject for policies attached to wsdl:Port, wsdl:Binding, and wsdl:PortType elements in WSDL. The possible points of attachment for each subject are listed in figure 9.8.

Figure 9.8. To compute the effective policy for a message exchange, one needs to combine the policies attached to four different subjects: Service, Endpoint, Operation, and Message. Policies can be attached to each of these subjects at the attachment points shown in this diagram.

WS-PolicyAttachment provides two mechanisms for attaching policy assertions to any element with a WSDL document.

  1. Using a child element named wsp:PolicyReference:
    <wsp:PolicyReference
    URI="#OurEndpointPolicy" wsdl:required="true"/>
  2. Using an attribute named wsp:PolicyURIs:
    <wsdl:binding
    wsp:PolicyURIs="#OurEndpointPolicy"
    ...>
    ...
    </wsdl:binding>

The first of these mechanisms is not always legal, since WSDL does not allow extension elements under all WSDL elements. WS-PolicyAttachment provides the second mechanism as well.

In both cases, URIs are used to refer to policy assertions defined elsewhere. For policy definitions that are available as part of the same WSDL document, the URIs take the form of #Id where Id refers to the policy’s identifier as given by its wsu:Id attribute. Listing 9.4 shows an example.

Listing 9.4. Attaching a policy to WSDL

Naturally, the client needs to combine all the subject-specific policies into one policy to understand the requirements of the service.

So far, we have described a generic policy framework for ensuring interoperability in web services. In particular, we

  • Described the basic ideas of policy and policy intersection.
  • Introduced the syntax provided by WS-Policy for expressing policy alternatives and illustrated it using a few basic assertions defined by WS-PolicyAssertions.
  • Illustrated how WS-MetadataExchange and WS-PolicyAttachment can be used to fetch policies.

Now, it is time to look at how this generic framework can be used to ensure interoperability between security solutions. There is only one extension that we need to make the generic policy framework work; we need to standardize the security-related policy assertions we are going to use as part of policy alternatives in a WS-Policy document. WS-SecurityPolicy does exactly this. Let’s study it in the next section.

9.4. WS-SecurityPolicy

WS-SecurityPolicy provides security-related assertions that can be used in WS-Policy documents to express the requirements, capabilities, and constraints of a web services security implementation. In particular, WS-SecurityPolicy standardizes assertions related to usage of WS-Security, WS-Trust, and WS-SecureConversation.

The assertions defined by WS-SecurityPolicy can be classified into four groups based on the policy subjects they can be associated with.

  1. Policy assertions with endpoints as subjects; in other words, security policies that can be set at the endpoint level.
  2. Policy assertions with operations as subjects; in other words, security policies that can be set per operation.
  3. Policy assertions with messages as subjects; in other words, security policies defined at the message level.
  4. Policy assertions that cannot be directly associated with a subject. These assertions can only be nested into other assertions.

Observe that WS-SecurityPolicy does not describe any assertions whose subject is a service. Figure 9.9 further classifies the assertions for endpoints, operations, and messages.

Figure 9.9. Classification of assertions defined by WS-SecurityPolicy based on the subjects they can be associated with: Endpoints, Operations, and Messages

To help you understand the policy assertions, we will show you different kinds of policy examples. We will start with examples of policies defined at the endpoint level.

9.4.1. Security assertions for endpoints

Before we start to learn the assertions defined by WS-SecurityPolicy for endpoints, it is helpful to understand how the designers of WS-SecurityPolicy approached this problem.

Previously, when discussing the challenges of interoperability between security solutions, we listed (in table 9.1) a large number of potential variations between security implementations that can break interoperability. The task that the designers of WS-SecurityPolicy had on their hands was to come up with policy assertions that unambiguously describe the position a security implementation should take on each possible variation. As there are too many possible variations, the trivial approach of simply defining one assertion per variation will result in a combinatorial explosion.

The designers of WS-SecurityPolicy attacked this problem by recognizing that only a few combinations of these variations are commonly seen in the real world. In fact, most real-world security implementations can be seen as following one of the three security usage patterns shown in figure 9.10.

Figure 9.10. WS-SecurityPolicy identifies three common security patterns and defines how security policies should be bound to endpoints in each.

In words, these three possibilities can be described as:

  1. Endpoints rely on a secure transport channel (such as an HTTPS channel). Security at such endpoints is in transport binding.
  2. Endpoints take care of security at a message level and use the same tokens for message protection in either direction (request and reply). Security at such endpoints is in symmetric binding.
  3. Endpoints take care of security at a message level and use different tokens for message protection depending on the direction of message exchange. Security at such endpoints is in asymmetric binding.

For each of these security usage patterns, WS-SecurityPolicy defines assertions for:

  • The tokens needed
  • Algorithms and key strengths
  • Layout of elements in the WS-Security header
  • Order of protections such as encryption and signatures
  • Other required elements such as timestamps in the WS-Security header

In addition to assertions related to the security usage pattern, WS-SecurityPolicy defines two other kinds of assertions with regards to an endpoint’s security policies.

  1. Assertions about the conformance levels required with WS-Security and WS-Trust. We can assert that the other party must be able to resolve various types of security token references defined by WS-Security.
  2. Assertions about the supporting tokens we need in addition to the tokens required by each security usage pattern supported by the endpoint. For instance, we may specify that a SAML assertion is needed.

We will look at examples of all these assertions in this section. We will start with examples of the assertions that can be used to specify one of the three security usage patterns described in figure 9.10.

Assertion for security pattern 1: TransportBinding

The security policy of an endpoint that is secured using transport-layer security is described using a TransportBinding assertion. As part of the TransportBinding assertion, the endpoint can specify the kind of transport-layer security it is willing to accept. It can state that it requires an HTTPS protocol with a specific key strength. Listing 9.5 shows how to put this information in a WS-Policy document.

Listing 9.5. Example of TransportBinding in WS-SecurityPolicy describing endpoint-level requirements

This example is quite simple—it says that we are using HTTPS for the transport. Let’s next look at an example of the assertions defined for the second security usage pattern described in figure 9.10.

Assertion for security pattern 2: SymmetricBinding

Recall that endpoints that use the same tokens for message protection in both directions (request and reply) are said to be using symmetric binding. An example of a token that can be used that way is a Kerberos ticket. Figure 9.11 shows a sample interaction that is secured in both directions using a Kerberos ticket. The source endpoint in this interaction obtains a Kerberos ticket from a WS-Trust STS (described in section 8.5.1).

Figure 9.11. Sample interaction that satisfies the SymmetricBinding assertion shown in listing 9.6.

Listing 9.6 shows how the service provider shown in figure 9.11 can assert that service consumers must use a Kerberos ticket issued by a specific WS-Trust STS to encrypt/sign messages to and from the service provider endpoint.

Listing 9.6. Example of SymmetricBinding in WS-SecurityPolicy describing endpoint-level requirements

In listing 9.6 we are asserting that the initiator should use a token issued by a specific STS . The IncludeToken attribute on the IssuedToken element needs further explanation. This attribute can take four different values to indicate the different possibilities described in table 9.2.

Table 9.2. Possible values of the IncludeToken attribute defined by WS-SecurityPolicy

URI[1]

Description

.../Never The security token must never be sent along with the message. It must always be referred to using an external reference. Refer to an X509 certificate by issuer and serial number (or other external reference mechanisms for certificates) instead of embedding the certificate.
.../Once Only include the token in the first message from the initiator to the recipient. For all subsequent messages in either direction, refer to the token using an external reference.
.../AlwaysToRecipient Always include the token in messages from initiator to recipient. Never include the token in messages from recipient to initiator.
.../Always Include the token in all messages in either direction.

1 To keep the text in the table readable, we have only shown the last component of the URIs. Replace “...” in the URIs with http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken

Figure 9.11 is an example of the assertions defined for the third security usage pattern described in figure 9.11.

Assertion for security pattern 3: AsymmetricBinding

Recall that asymmetric binding, as opposed to symmetric binding, is where the endpoints use different tokens for message protection depending on the direction of message exchange. Figure 9.12 shows a sample interaction that fits into this pattern.

Figure 9.12. Sample interaction that matches the AsymmetricBinding assertion shown in listing 9.7

Listing 9.7 shows how you can use the AsymmetricBinding assertion defined by WS-SecurityPolicy to require the use of two different X.509 certificates—one belonging to the source endpoint and another belonging to the destination endpoint—for protecting request and response messages.

Listing 9.7. Example of AsymmetricBinding in WS-SecurityPolicy describing endpoint-level requirements

In all three security usage patterns, we need to deal with interoperability issues that can arise out of mismatches in algorithms and key strengths between different endpoints. The next assertion we discuss is designed to deal with this problem.

AlgorithmSuite assertion

Instead of defining one assertion per algorithm and key strength combination, WS-SecurityPolicy groups commonly used combinations of algorithms and key strengths into algorithm suites. An endpoint can assert its support for one or more suites using the AlgorithmSuite assertion. We can specify the following snippet under the Policy element to state that the endpoint supports the Basic algorithm suite with 256 bits of key strength.

<sp:AlgorithmSuite>
  <wsp:Policy><sp:Basic256/></wsp:Policy>
</sp:AlgorithmSuite>

The AlgorithmSuite assertion can be nested in any of the three security usage pattern assertions we have defined previously: TransportBinding, SymmetricBinding, and AsymmetricBinding.

We will next discuss the Layout assertion, which can also be nested in any of the three security usage pattern assertions we have defined previously. It is only useful when a WS-Security header entry is used to provide message-level security.[1]

1 Note that a message secured using a point-to-point secure channel such as HTTPS can also have a WS-Security header entry in it.

Assertion related to layout of elements in the WS-Security header entry

In chapters 3-8, you have learned a lot about security tokens that can be included as part of a Security header entry in a SOAP message. In these chapters, we have also talked about the ordering of tokens in the Security header entry. In chapter 6, when introducing the security tokens used for encryption, we told you that the ReferenceList of elements that have been encrypted must be prepended to the Security header entry to make the decryption process easy for receivers of the message. But standards cannot always mandate a specific order of elements in the Security header. At the same time, implementations may be limited in their ability to handle elements in arbitrary order; for the sake of simplicity and/or efficiency, implementations may assume particular layouts of elements within the Security header.

So, if we want to ensure interoperability between arbitrary security implementations, we need a standard way to declare the capabilities and constraints of either endpoint in handling different layouts of elements in the Security header entry. WS-SecurityPolicy makes this possible by defining a Layout assertion. This assertion can be used to specify four different kinds of layouts, as described in table 9.3.

Table 9.3. Four possible layouts that can be asserted using WS-SecurityPolicy

Layout name

Description

Strict This layout is probably the easiest to handle for WS-Security implementations. Tokens are declared before they are used, signed elements within the WS-Security header appear before their signature, and ReferenceList occurs before any of the EncrypedData elements within the WS-Security header are referred in the list.
Lax Elements can occur in any order as long as the WS-Security spec is not violated.
LaxTimestampFirst Same as Lax except that the first entry in the WS-Security header must be a wsu:Timestamp element defined by WS-Security
LaxTimestampLast Same as Lax except that the last entry in the WS-Security header must be a wsu:Timestamp element defined by WS-Security

If we want to specify the layout to be strict, here is how we can do it.

<sp:Layout>
  <wsp:Policy><sp:Strict/></wsp:Policy>
</sp:Layout>

One of the elements in the WS-Security header we discussed in table 9.2 is wsu:Timestamp. Let’s next look at assertions related to that.

Timestamp assertion

WS-Security defines but does not mandate the inclusion of a Timestamp element. It is almost always desirable to include it. Implementations that want to make the Timestamp element mandatory can do so using an assertion defined by WS-SecurityPolicy. Using this assertion is quite simple: Just nest an <sp:IncludeTimestamp/> element in the TransportBinding, SymmetricBinding, or AsymmetricBinding assertions, whichever is declared in the endpoint’s policy document.

So far, we have seen assertions related to the three security usage patterns described in figure 9.10. As we described previously, there are two other kinds of endpoint-related assertions that WS-SecurityPolicy defines.

  • Assertions about the conformance levels required with WS-Security and WS-Trust
  • Assertions about the supporting tokens we need in addition to the tokens required by each security usage pattern supported by the endpoint

Let’s next look at the assertions related to conformance with WS-Security and WS-Trust.

Assertions related to conformance with WS-Security and WS-Trust

WS-SecurityPolicy defines assertions that an endpoint can use to declare the conformance it requires with WS-Security 1.0/1.1 and WS-Trust 1.0. As we said before, these assertions become necessary because several options defined by these specifications and implementations may or may not support all options.

WS-Security provides options for referring to a security token. A security token can be embedded within a request or simply referred to using some token identification mechanism. Let’s say an endpoint prefers to refer to X.509 certificates by issuer name and serial number as shown in the following:

<wsse:SecurityTokenReference>
  <ds:X509IssuerSerial>
    <ds:X509IssuerName>
      CN=Prasad Chodavarapu,OU=Authors,O=Manning,...
    </ds:X509IssuerName>

    <ds:X509SerialNumber>
      1120945714
    </ds:X509SerialNumber>
  </ds:X509IssuerSerial>
</wsse:SecurityTokenReference>

How does such an endpoint declare that a client endpoint will need the capability to resolve references to certificates based on issuer and serial numbers? The solution is straightforward: The endpoint should declare in its policy that any party seeking to interact with it must support security token references based on issuer and serial number, as defined in WS-Security 1.0. The following assertion does this:

<sp:Wss10>
  <wsp:Policy>
    <sp:MustSupportRefIssuerSerial/>
  </wsp:Policy>
</sp:Wss10>

This example should have given you a good idea of how WS-SecurityPolicy seeks to solve the interoperability problems that arise out of options defined by WS-Security and WS-Trust. Table 9.4 shows the complete list of assertions defined by WS-SecurityPolicy for declaring conformance with various optional aspects of WS-Security 1.0/1.1 and WS-Trust 1.0.

Table 9.4. Assertions defined by WS-SecurityPolicy to declare conformance with WS-Security 1.0/1.1 and WS-Trust 1.0 specifications

Specification name and version

Top-level assertion element defined by WS-SecurityPolicy

Assertions that can be nested

WS-Security 1.0 Wss10 MustSupportRefKeyIdentifier
MustSupportRefIssuerSerial
MustSupportRefExternalUri
MustSupportRefEmbeddedToken
WS-Security 1.1 Wss11 MustSupportRefKeyIdentifier
MustSupportRefIssuerSerial
MustSupportRefExternalUri
MustSupportRefEmbeddedToken
MustSupportRefThumbprint
RequireSignatureConfirmation
WS-Trust 1.0 Trust10 MustSupportClientChallenge
MustSupportServerChallenge
RequireClientEntropy
RequireServerEntropy
MustSupportIssuedTokens

Most of the assertions listed in table 9.4 have self-explanatory names so we will not be describing them in detail here. Refer to the WS-SecurityPolicy specification if you need formal definitions for each of these assertions.

Let’s now discuss the last class of WS-Security defined policy assertions that can be attached to an endpoint. These assertions let an endpoint mandate the presence of supporting tokens in addition to the tokens required by the security usage pattern supported by the endpoint.

Supporting token assertions

WS-SecurityPolicy defines four kinds of supporting tokens, as described in table 9.5.

Table 9.5. Four types of supporting tokens defined by WS-SecurityPolicy

Supporting token type

Description

SupportingTokens Tokens included in addition to the token required by the security usage pattern (binding). The inclusion of tokens may necessitate the signing/encryption of more parts.
SignedSupportingToken Same as SupportingTokens with the additional assertion that the supporting tokens must be signed using the mechanism described in the security binding. In the case of transport binding, no signing is necessary, as the binding does not use message-level signatures.
EndorsingSupportingToken Same as SupportingTokens with the additional assertion that the supporting token should sign the signature produced by the security binding. In the case of transport binding, the endorsing token should simply sign the timestamp in the WS-Security header, as the binding does not produce a message-level signature.
SignedEndorsingSupportingToken Combination of SignedSupportingToken and EndorsingSupportingToken.

Suppose an endpoint wants to specify that we need a SAML 1. 0 token as defined in the SAML Token Profile 1.0 for WS-Security. Here is how it can do so:

<sp:SupportingTokens>
  <wsp:Policy>
    <sp:WssSamlV10Token10
      sp:IncludeToken=".../Always" />
  </wsp:Policy>
</sp:SupportingTokens>

Now that you understand several assertions that can be used to describe the security policy of an endpoint, let’s look at the security assertions that describe message-level policies.

9.4.2. Security assertions for messages

Up until now, you’ve seen how WS-SecurityPolicy–defined assertions can be used to specify the requirements, constraints, and capabilities of an endpoint. In this section, we will describe how message-level policies can be defined using the assertions defined by WS-SecurityPolicy.

WS-SecurityPolicy provides assertions to mandate:

  1. Signing: There are two different kind of assertions that can be made about signing:
    1.1 Signing of specific parts of a message You can sign the entirety of the SOAP body or headers identified by their namespace and, optionally, names.
    1.2 Signing of selected elements in a message The elements to sign can be identified using XPath.
  2. Encryption: There are two different kind of assertions that can be made about encryption:
    2.1 Encrypting of specific parts of a message You can encrypt the entirety of the SOAP body or headers identified by their namespace and, optionally, names.
    2.2 Encrypting of selected elements in a message The elements to encrypt can be identified using XPath.
  3. Presence: Specific elements, identified by their XPaths, can be mandated using assertions defined by WS-SecurityPolicy.

Listing 9.8 illustrates all of these assertions.

Listing 9.8. Example of WS-SecurityPolicy assertions that describe message-level requirements

Let’s discuss the assertions defined by WS-SecurityPolicy for declaring operation-level policies.

9.4.3. Security assertions for operations

In table 9.5, we have seen SupportingTokens, the only types of assertion defined by WS-SecurityPolicy that can be associated per operation. There is nothing further to add here about the assertions for operations.

In the past few sections, you have learned about the assertions defined by WSSecurityPolicy. Table 9.6 summarizes the material we covered.

Table 9.6. Recap of WS-SecurityPolicy

Policy subject

Assertion topics

Endpoint Security usage pattern (binding) Conformance with WS-Security and WS-Trust Supporting tokens
Message Signing of message parts/elements Encryption of message parts/elements Required elements
Operation Supporting tokens

As we stated before, WS-SecurityPolicy is new, complex, and incomplete. We will discuss its limitations in the next section.

9.4.4. Limitations of WS-SecurityPolicy

We started this chapter with a vision of declarative security. Any declarative security mechanism has two facets: One is external and supports interoperability and negotiation. Another is internal, which lets an implementation be derived from those declarations. Clearly, WS-SecurityPolicy only aims for the external facet. As yet, it is not suitable for generating a security implementation by itself. We cannot specify the LDAP directory to be used for authentication. SOA security vendors rely on proprietary extensions to fill this void.

Even when we are declaring to others the kind of security we are implementing, WS-SecurityPolicy falls short. We cannot specify the CA to be used for certificates. We can say we need a SAML token, but we cannot specify that the SAML token must contain an authorization assertion. There are several other small details that are needed by a security policy statement but are not covered by WS-SecurityPolicy.

It is worth noting that there are other standards that focus on codification of specific kinds of policies. A standard named XACML (Extensible Access Control Markup Language) provides a language to codify access control policies. XACML is not widely adopted so we will not be covering it in this book.

To summarize, WS-SecurityPolicy supports declarative security that is comprehensive enough for interoperability and negotiation, despite falling short in providing details for a full implementation.

9.5. Summary

This chapter covers one of the emerging topics in SOA security management. The standards described in this chapter, WS-Policy and WS-SecurityPolicy, are not yet widely used. Yet, several vendors are working on incorporating these standards into their tools.

Let’s recap what we learned in this chapter. Declarative security is driven by three different goals: interoperability among applications, enforcing security policies consistently across several different security solutions in an enterprise, and ease of application development. Of these, the standards currently address only the first goal: interoperability.

Interoperability challenges arise from the choices that applications make in implementing standards. We can eliminate the unneeded choices by adhering to WS-I Basic Security Profile. By itself, it will reduce the complexity of implementation addressing most common requirements.

When our requirements go beyond WS-I Basic Security profile, we can declare the security we need using WS-SecurityPolicy. If you followed the chapter so far, you should understand the details of WS-SecurityPolicy: how to read the policy statements, how to exchange them with another application, and how to even specify a policy with the right syntax.

The standards we have described in this chapter are all very recent and are not yet widely used. It is very likely that they will evolve further to meet real-world needs. We expect future enhancements or modifications to be incremental in nature; the effort you have put in into understanding this chapter should prove to be useful.

Over time, we can expect support from toolkits and solutions to make your job of dealing with security using declarative means easier. For instance, policy discovery, exchange, negotiation, and security decisions can be handled by a framework, without involving any code from the developer side.

This concludes the discussion of standards in implementing security in SOA. Chapter 10 will focus on the real-world issues in implementing solutions built on these standards. We expect more standards to emerge in SOA security over time; the ones we’ve discussed so far will form the core of SOA security.

Suggestions for further reading

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.217.5