11 Replies Latest reply on Aug 5, 2014 11:47 AM by eric.wittmann

    API Management: Policies

    eric.wittmann

      Overview

      The real meat of the API Management Gateway is the concept of Policies.  When the Gateway is satisfying an API request made by a client application, it first creates a Policy Chain for the request.  The Policy Chain is a sequence of Policies that are executed.  The policies are applied (in sequence) to the inbound request.  Once the policies are applied, the inbound request is sent to the back end service implementation.  The policies are then once again applied (in reverse sequence) to the response received from the back end service implementation.

       

      Policies can be configured at the Application, Service, and Plan levels with the API Manager webapp.  The order in which policies are applied as as follows:

       

      1. Receive Inbound Request from client application
        1. Apply Application Policies
        2. Apply Plan Policies
        3. Apply Service Policies
      2. Proxy Request to Back End
      3. Receive Response from Back End
        1. Apply Service Policies
        2. Apply Plan Policies
        3. Apply Application Policies
      4. Send Response to client application

       

      Diagrams are always helpful!

      APIManager-PolicyChain.png

      What are Policies?

      Policies implement all of the governance logic that we want to apply to an inbound request.  Every Policy is an instance of a Policy Definition (which may built-in to the system or contributed by third parties).  The Policy Definition includes meta-information about the Policy such as its type (access, metering, throttling, etc).  The type is useful for categorizing policies and displaying them in the user interface (when managing services and applications) but is unimportant to the Gateway.

       

      Here are some typical examples of Policies:

       

      Access Policies - these types of policies control access to the Service.  These policies could be configured to grant or deny access to the service based on authentication credentials included in the Request (e.g. BASIC authentication credentials passed in an HTTP Authorization header).  They may be configured in various ways, for example to leverage existing sources of identity such as an LDAP directory.  Here are some examples of Access Policies:

      • Pass-Through Authentication Policy
      • BASIC Authentication Policy using LDAP as the source of identity
      • BASIC Authentication Policy using a Database as the source of identity
      • OpenId Authentication Policy
      • Authorization Policy using Drools to grant/revoke access
      • IP Whitelist/Blacklist Policy

       

      Throttling/Metering Policies - these policies track aggregate statistics such as # of requests performed per unit of time, typically for the purpose of billing or throttling.

       

      Metrics Policies - these policies track metrics for the purpose of reporting significant statistics to Service and Application owners.

       

      Custom Policies - this is a generic class of policies to cover domain/business specific logic that should be applied.

        • 1. Re: API Management: Policies
          objectiser

          I was originally thinking that the metering and metrics collection would be a standard part of the gateway - however having them as policies, as you suggest, would give greater flexibility in terms of (1) whether they are required (which benefits performance if they are not), and (2) how they are reported - allowing for various target solutions to be used to collect and report on that information. However we should probably also support our own "out of the box" basic reporting mechanism based on the collection of this data.

          • 2. Re: API Management: Policies
            eric.wittmann

            Agreed - if they are implemented as policies then we can support integration with external data reporting services such as datadog.

             

            I'm also not necessarily assuming that all policies will be configured the same way in the UI.  For example, the UI might have a specific screen for Authentication/Authorization and a different one for Metrics.  That would allow users to more easily enable/disable/configure these policies, without having to know that, under the covers, everything is just a Policy.

            • 3. Re: API Management: Policies
              msavy

              One suggestion I posited when speaking withEric was that there could be use-cases where context information could be passed from one policy to the next. I need to think of some more convincing use-cases, but a simple example would be a combination of, for instance, ip address filtering plus rate-limiting.

               

              Let's say that we decide certain ranges of IP addresses shall be designated as `throttled-region` and another as `unthrottled-region`; the access policy makes the determination of whether the request is permitted at all, followed by its designation. This context is then passed to the rate-limiting policy which then discriminates using the aforementioned designations.

               

              You could imagine something similar for authentication (e.g. `administrator` gets unlimited requests; `developer` isn't included in any metrics to avoid pollution).

               

              I realise this could add complexities which may outweigh the possible benefits, given that we'd potentially introduce coupling/chained dependencies.

               

              What do you all think?

               

              Edit: Fixed a word.

              • 4. Re: API Management: Policies
                eric.wittmann

                I'm not against a context object that gets passed along during processing of the policies.  We certainly have a need for a persistent context object in any case so that we can implement any aggregating policies like metering/throttling.

                 

                That said, your example doesn't strictly speaking require a context object - it could be controlled by adding a header to the ServiceRequest object (indicating some designation).  Of course doing that is less than ideal, since the header would then get passed to the back-end service (something we probably don't want in this case, but we might want for other use-cases).

                 

                So ultimately I think I'm a +1 for a conversation scoped context object that allows easy chaining of policies.  It implies dependencies, but that's perhaps a separate (management) problem.

                • 5. Re: API Management: Policies
                  msavy

                  You're right; perhaps the second example is a better use-case:

                   

                  - Auth Policy authenticates Adam and designates `developer` (Inbound pol chain).

                  - Metrics Policy sees `developer` and doesn't log the interaction (Inbound + Outbound pol chains).

                  • 6. Re: API Management: Policies
                    objectiser

                    Eric Wittmann wrote:

                     

                    So ultimately I think I'm a +1 for a request scoped context object that allows easy chaining of policies.  It implies dependencies, but that's perhaps a separate (management) problem.

                     

                    Agree - but not sure whether it should just be request scoped - might need to also carry the information back through the response chain.

                    • 7. Re: API Management: Policies
                      eric.wittmann

                      What's this now?  I *clearly* wrote "conversation scoped" in my original post.  Ahem.

                      • 8. Re: API Management: Policies
                        msavy

                        +1 that's what I meant with those examples; your terminology is better .

                        • 9. Re: API Management: Policies
                          objectiser

                          Nice edit

                          • 10. Re: API Management: Policies
                            msavy

                            Any thoughts on what form the conversation might take? Let's imagine that each request-response to APIMan has its own context, which in turn contains the relevant conversation. I know we want to avoid the "bloated context anti-pattern" and limit implicit coupling wherever possible.

                             

                            Obviously a simple map immediately springs to mind, but I'm thinking more specifically of whether it might make sense to allow arbitrary keys and values (with generics to make it as safe as possible), or perhaps tie it down in some way that might make it easier to manage (like a special key type, or even just strings)?

                            • 11. Re: API Management: Policies
                              eric.wittmann

                              I think a simple Map<String,Object> should be sufficient.  Probably don't want to over-think it.

                               

                              I could be convinced I'm wrong, but don't currently see a compelling reason to add complexity.