Apiman Policies

The most important runtime concept in Apiman is the policy. Policies are configured in the API Manager and then applied at runtime by the API Gateway. This section of the guide provides more information about each of the policies available in Apiman, what they do, and how they can be configured.

Policy Types

Apiman supports several policy types like security, limiting, modification and others which are explained in the following.

Security Policies

There are authentication-based policies which manage access to an API is governed by the identity of the user. And there are authorization-based policies which manage access to an API, or specific resources provided by an API, is governed by the role(s) assigned to a user.

Apiman supports these types of security policies:

  • Authorization Policy

  • BASIC Authentication Policy

  • CORS Policy

  • Header Allow/Deny Policy

  • HTTP Security Policy

  • Ignored Resources Policy

  • IP Blacklist Policy

  • IP Whitelist Policy

  • JWT Policy

  • Keycloak OAuth Policy

  • SOAP Authorization Policy

  • Time Restricted Access Policy

Limiting Policies

Some Apiman policies provide an all-or-nothing level of control over access to managed APIs. For example, IP Blacklist or Whitelist policies either block or enable all access to a managed API, based on the IP address of the client. Rate limiting and quota policies provide you with more flexible ways to govern access to managed APIs. With rate limiting and quota policies, you can place limits on either the number of requests an API will accept over a specified period of time, or the total number of of bytes in the API requests. In addition, you can use combinations of fine-grained and coarse-grained rate limiting policies together to give you more flexibility in governing access to your managed API.

The ability to throttle API requests based on request counts and bytes transferred provides even greater flexibility in implementing policies. APIs that transfer larger amounts of data, but rely on fewer API requests can have that data transfer throttled on a per byte basis. For example, an API that is data intensive, will return a large amount of data in response to each API request. The API may only receive a request a few hundreds of times a day, but each request may result in several megabytes of data being transferred. Let’s say that we want to limit the amount of data transferred to 6GB per hour. For this type of API, we could set a rate limiting policy to allow for one request per minute, and then augment that policy with a transfer quota policy of 100Mb per hour.

Each of these policies, if used singly, can be effective in throttling requests. Apiman, however, adds a layer of flexibility to your use of these policy types by enabling you to use them in combinations.

Apiman supports these types of limiting policies:

  • Quota Policy

  • Rate Limiting Policy

  • Transfer Quota Policy

Modification Policies

Apiman supports these types of modification policies:

  • JSONP Policy

  • Simple Header Policy

  • URL Rewriting Policy

Other Policies

Apiman supports these types of other policies:

  • APIKey Policy

  • Caching Resource Policy

Policies

Authorization Policy

Description

This policy enables fine grained authorization to API resources based on authenticated user roles. This policy can be used to control precisely who (authenticated users) are allowed to access the API, at an arbitrarily fine-grained level.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration of this policy consists of a number of rules that are applied to any inbound request to the API. Each rule consists of a regular expression pattern, an HTTP verb, and the role that an authenticated user must possess in order for access to be granted.

It’s very important to note that this policy must be configured after one of the standard Apiman authentication policies (e.g. the BASIC Authentication policy or the Keycloak OAuth Policy). The reason is that an Authentication policy is responsible for extracting the authenticated user’s roles, which is data that is required for the Authorization Policy to do its work.
  • rules (array) : Array of rules - each rule is applied only if it matches the current request.

    • pathPattern (string regexp) : Pattern that must match the request resource path you’d like the policy to be applicable to.

    • verb (string) : The HTTP verb that must match the request you’d like the policy to be applicable to.

    • role (string) : The role the user must have if this pattern matches the request.

  • multimatch (boolean) : Should the request pass when any or all of the authorization rules pass? Set to true if all rules must match, false if only one rule must match.

  • requestUnmatched (boolean) : If the request does not match any of the authorization rules, should it pass or fail? Set to true if you want the policy to pass when no rules are matched.

Sample Configuration

{
   "rules" : [
   	{
   		"pathPattern": "/admin/.*",
   		"verb": "*",
   		"role": "admin"
   	},
   	{
   		"pathPattern": "/.*",
   		"verb": "GET",
   		"role": "user"
   	}
   ],
   "multiMatch": true,
   "requestUnmatched": false
}

BASIC Authentication Policy

Description

This policy enables HTTP BASIC Authentication on an API. In other words, you can use this policy to require clients to provide HTTP BASIC authentication credentials when making requests to the managed API.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The BASIC Authentication policy has a number of configuration options. There are several top level configuration properties:

  • realm (string) : defines the BASIC Auth realm that will be used when responding with an auth challenge (when authentication is missing or fails)

  • forwardIdentityHttpHeader (string) : if authentication succeeds, indicates the name of an HTTP header to send with the principal/identity of the authenticated user (useful when the back-end API needs to know the identify of the authenticated user)

  • requireTransportSecurity (boolean) : set to true if this policy should fail when receiving a message over an unsecured communication channel (in other words, enabling this will require clients to use https)

  • requireBasicAuth (boolean) : set to true if BASIC authentication credentials are required (set to false if alternative authentication mechanisms, such as OAuth, are also supported)

Additionally, one of the following complex properties must be included in the configuration, indicating whether Apiman should use JDBC, LDAP, or Static (not recommended for production) information as the source of identity used to validate provided user credentials.

  • jdbcIdentity (object) : included when you wish to use JDBC to connect to a database containing user and password information

    • type (enum) : what type of JDBC connection to use - options are 'datasource', 'url'

    • datasourcePath (string) : the JNDI path of the datasource to use (only when type is 'datasource')

    • jdbcUrl (string) : the URL to the JDBC database (only when type is 'url')

    • username (string) : the Username to use when connecting to the JDBC database (only when type is 'url')

    • password (string) : the Passowrd to use when connecting to the JDBC database (only when type is 'url')

    • query (string) : the SQL query to use when searching for a user record - the first parameter passed to the query will be the username, the second parameter will be the (optionally hashed) password

    • hashAlgorithm (enum) : the hashing algorithm used when storing the password data in the database

    • extractRoles (boolean) : set to true if you also want to extract role information from the database

    • roleQuery (string) : a SQL query to use when extracting role information - the first parameter passed to the query will be the username

  • ldapIdentity (object) : included when you wish to connect to LDAP when validating user credentials

    • url (string) : the URL to the LDAP server

    • dnPattern (string) : the pattern to use when binding to the LDAP server (you can use ${username} in this pattern)

    • bindAs (enum) : whether to bind directly to LDAP as the authenticating user (UserAccount), or instead to bind as a service account and then search LDAP for the user’s record (ServiceAccount)

    • credentials (object) : an object with two properties: 'username' and 'password' - credentials used when initially binding to LDAP as a service account

    • userSearch (object) : an object with two properties: 'baseDn' and 'expression' - used to search for the user’s LDAP record so that it can be used to re-bind to LDAP with the appropriate password

    • extractRoles (boolean) : set to true if you wish to extract role information from LDAP

    • membershipAttribute (string) : the attribute representing the user’s membership in a group - each value should be a reference to another LDAP node

    • rolenameAttribute (string) : the attribute on a role LDAP node that represents the name of the role

  • staticIdentity (object) : used mostly for testing purposes - allows you to provide a static set of user names and passwords (do not use in production!)

Sample Configuration (LDAP)

Here is an example of the JSON configuration you might use when configuring a BASIC Authentication policy that uses LDAP to validate the inbound credentials:

{
   "realm" : "Example",
   "forwardIdentityHttpHeader" : "X-Identity",
   "requireTransportSecurity" : true,
   "requireBasicAuth" : true,
   "ldapIdentity" : {
      "url" : "ldap://example.org",
      "dnPattern" : "cn=${username},dc=example,dc=org",
      "bindAs" : "UserAccount",
      "extractRoles" : true,
      "membershipAttribute" : "memberOf",
      "rolenameAttribute" : "objectGUID"
   }
}

Sample Configuration (JDBC)

Here is an example of the JSON configuration you might use when configuring a BASIC Authentication policy that uses JDBC to validate the inbound credentials:

{
   "realm" : "Example",
   "forwardIdentityHttpHeader" : "X-Identity",
   "requireTransportSecurity" : true,
   "requireBasicAuth" : true,
   "jdbcIdentity" : {
      "type" : "url",
      "jdbcUrl" : "jdbc:h2:mem:UserDB",
      "username" : "dbuser",
      "password" : "dbpass123#",
      "query" : "SELECT * FROM users WHERE userid = ? AND pass = ?",
      "hashAlgorithm" : "SHA1",
      "extractRoles" : true,
      "roleQuery" : "SELECT r.rolename FROM roles r WHERE r.user = ?"
   }
}

Caching Policy (Deprecated)

Description

This policy is deprecated. Use Caching Resources Policy instead.

Caching Resources Policy

Description

Allows caching of API responses in the Gateway to reduce overall traffic to the back-end API. The Resource Caching Policy can cache requests based on their URL path, http method and specific status code.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

If you want to cache POST requests you have to enable stateful request payload inspection in your API Implementation.

The configuration parameters for an Caching Resources Policy are:

  • ttl (long) : Number of seconds to cache the response.

  • cachingResourcesSettingsEntries (array of objects) : The list of matching rules representing the resources to be cached.

    • httpMethod (enum) : The HTTP method to be controlled by the rule. Valid values are:

    • pathPattern (string regexp) : A regular expression used to match the REST resource being cached.

    • statusCode (string): Either a single number representing a specific status code or * to cache all status codes.

Sample Configuration

{
  "ttl" : 60,
  "cachingResourcesSettingsEntries" : [
    { "httpMethod" : "GET",  "pathPattern" : "/customers", "statusCode" : "200" },
    { "httpMethod" : "POST", "pathPattern" : "/customers/.*/orders", "statusCode": "*" },
    { "httpMethod" : "*",    "pathPattern" : "/customers/.*/orders/bad_debts", "statusCode": "403" }
  ]
}

CORS Policy

Description

A policy implementing CORS (Cross-origin resource sharing): a method of defining access to resources outside the originating domain. It is principally a security mechanism to prevent the loading of resources from unexpected domains, for instance via XSS injection attacks.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-cors-policy",
    "version": "1.5.7.Final"
}

Configuration

The configuration options available, are:

Table 1. CORS policy configuration
Option Type Description Default

errorOnCorsFailure

Boolean

Error on CORS failure When true, any request that fails CORS validation will be terminated with an appropriate error. When false, the request will still be sent to the backend API, but the browser will be left to enforce the CORS failure. In both cases valid CORS headers will be set.

true

allowOrigin

Set<String>

Access-Control-Allow-Origin List of origins permitted to make CORS requests through the gateway. By default same-origin is permitted, and cross-origin is forbidden. A special entry of * permits all CORS requests.

Empty

allowCredentials

Boolean

Access-Control-Allow-Credentials Whether response may be exposed when the credentials flag is set to true on the request.

false

exposeHeaders

Set<String>

Access-Control-Expose-Headers Which non-simple headers the browser may expose during CORS.

Empty

allowHeaders

Set<String>

Access-Control-Allow-Headers In response to preflight request, which headers can be used during actual request.

Empty

allowMethods

Set<String>

Access-Control-Allow-Methods In response to preflight request, which methods can be used during actual request.

Empty

maxAge

Integer

Access-Control-Max-Age How long preflight request can be cached in delta seconds.

Not included

Sample Configuration

{
   "exposeHeaders" : [
      "X-REQUESTS-REMAINING"
   ],
   "maxAge" : 9001,
   "allowOrigin" : [
      "https://foo.example",
      "https://bar.example"
   ],
   "errorOnCorsFailure" : true,
   "allowCredentials" : false,
   "allowMethods" : [
      "POST"
   ],
   "allowHeaders" : [
      "X-CUSTOM-HEADER"
   ]
}

Header Allow/Deny

The Header Allow/Deny Policy allows the user to control which incoming requests may be forwarded to the backend service. Permission is granted by adding values for a header.

When a request is received, the policy examines the HTTP headers. The configured rules are applied using a regular expression against the names and values. If these are permitted, the request is passed unmodified to the backend API. If they are not allowed, an HTTP 403 response is returned and the call to the backend service is not executed.

Configuration

Option Description Possible Values Default

Header Name

Name of the HTTP header, e.g. Host

Any string.

-

Allow request if header is missing

Determines whether the request is considered if a header is missing.

true/false

false

Allow request if no rules match

Determines whether the request is considered if no rule applies.

true/false

false

Header Rules

Allow request if value matches

Determines whether the request is considered if the value applies.

true/false

false

Header Value Regex

Defines the header value.

Any regex.

-

HTTP Security Policy

Description

Security-related HTTP headers can be set, such as HSTS, CSP and XSS protection.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-http-security-policy",
    "version": "1.5.7.Final"
}

Configuration

Table 2. HTTP security policy configuration
Option Type Description Default

frameOptions

Enum [DENY, SAMEORIGIN, DISABLED]

Frame Options Defines if, or how, a resource should be displayed in a frame, iframe or object.

DISABLED

xssProtection

Enum [OFF, ON, BLOCK, DISABLED]

XSS Protection Enable or disable XSS filtering in the UA.

DISABLED

contentTypeOptions

Boolean

X-Content-Type-Options Prevent MIME-sniffing to any type other than the declared Content-Type.

false

hsts

[_hsts]

HTTP Strict Transport Security Configure HSTS.

None

contentSecurityPolicy

contentSecurityPolicy

Content Security Policy CSP definition.

None

hsts

Table 3. HTTP Strict Transport Security (hsts): Enforce transport security when using HTTP to mitigate a range of common web vulnerabilities.
Option Type Description Default

enabled

Boolean

HSTS Enable HTTP Strict Transport

false

includeSubdomains

Boolean

Include subdomains

false

maxAge

Integer

Maximum age Delta seconds user agents should cache HSTS status for

0

preload

Boolean

Enable HSTS preloading Flag to verify HSTS preload status. Popular browsers contain a hard-coded (pinned) list of domains and certificates, which they always connect securely with. This mitigates a wide range of identity and MIITM attacks, and is particularly useful for high-profile domains. Users must submit a request for their domain to be included in the scheme.

false

contentSecurityPolicy

Table 4. CSP (contentSecurityPolicy): A sophisticated mechanism to precisely define the types and sources of content that may be loaded, with violation reporting and the ability to restrict the availability and scope of many security-sensitive features
Option Type Description Default

mode

Enum [ENABLED, REPORT_ONLY, DISABLED]

CSP Mode Which content security policy mode to use.

DISABLED

csp

String

Content Security Policy A valid CSP definition to apply

Empty string

Sample Configuration

{
   "contentSecurityPolicy" : {
      "mode" : "REPORT_ONLY",
      "csp" : "default-src none; script-src self; connect-src self; img-src self; style-src self;"
   },
   "frameOptions" : "SAMEORIGIN",
   "contentTypeOptions" : true,
   "hsts" : {
      "includeSubdomains" : true,
      "preload" : false,
      "enabled" : true,
      "maxAge" : 9001
   },
   "xssProtection" : "ON"
}

Ignored Resources Policy

Description

The ignored resources policy type enables you to shield some of an API’s resources from being accessed, without blocking access to all the API’s resources. Requests made to access to API resources designated as “ignored” result in an HTTP 404 (“not found”) error code. By defining ignored resource policies, Apiman enables you to have fine-grained control over which of an API’s resources are accessible.

For example, let’s say that you have an Apiman managed API that provides information to remote staff. The REST resources provided by this API are structured as follows:

/customers /customers/{customer id}/orders /customers/{customer id}/orders/bad_debts

By setting up multiple ignored resource policies, these policies can work together to give you more flexibility in how you govern access to to your API’s resources. What you do is to define multiple plans, and in each plan, allow differing levels of access, based on the paths (expressed as regular expressions)defined, for resources to be ignored. To illustrate, using the above examples:

This Path Results in these Resources Being Ignored

(empty)

Access to all resources is allowed

/customers

Denies access to all customer information

/customers/.*/orders

Denies access to all customer order information

/customers/.*/orders/bad_debts

Denies access to all customer bad debt order information

What happens when the policy is applied to an API request is that the Apiman Gateway matches the configured paths to the requested API resources. If any of the exclusion paths match, the policy triggers a failure with an HTTP return code of 404.

The IP-related policy types are less fine-grained in that they allow or block access to all of an API’s resources based on the IP address of the client application. We’ll look at these policy types next.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for an Ignored Resources Policy are:

  • rules (array of objects) : The list of matching rules representing the resources to be ignored.

    • verb (enum) : The HTTP verb to be controlled by the rule. Valid values are:

      • * (matches all verbs)

      • GET

      • POST

      • PUT

      • DELETE

      • OPTIONS

      • HEAD

      • TRACE

      • CONNECT

    • pathPattern (string regexp) : A regular expression used to match the REST resource being hidden.

Sample Configuration

{
  "rules" : [
    { "verb" : "GET",  "pathPattern" : "/customers" },
    { "verb" : "POST", "pathPattern" : "/customers/.*/orders" },
    { "verb" : "*",    "pathPattern" : "/customers/.*/orders/bad_debts"}
  ]
}

IP Blacklist Policy

Description

As its name indicates, the IP blacklist policy type blocks access to an API’s resources based on the IP address of the client application. The Apiman Management UI form used to create an IP blacklist policy enables you to use wildcard characters in specifying the IP addresses to be blocked. In addition, Apiman gives you the option of specifying the return error code sent in the response to the client if a request is denied. Note that an IP Blacklist policy in a plan overrides an IP Whitelist policy.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for an IP Blacklist Policy are:

  • ipList (array) : The IP address(es), and/or ranges of addresses that will be blocked from accessing the API.

  • responseCode (int) : The server response code. The possible values for the return code are:

    • 500 - Server error

    • 404 - Not found

    • 403 - Authentication failure

  • httpHeader (string) [optional] : Tells Apiman to use the IP address found in the given HTTP request header instead of the one associated with the incoming TCP socket. Useful when going through a proxy, often the value of this is 'X-Forwarded-For'.

Sample Configuration

{
  "ipList" : ["192.168.7.*"],
  "responseCode" : 500,
  "httpHeader" : "X-Forwarded-For"
}

IP Whitelist Policy

Description

The IP Whitelist Policy Type is the counterpart to the IP Blacklist Policy type. In the IP Whitelist policy, only inbound API requests from Client Apps, policies, or APIs that satisfy the policy are accepted.

The IP Blacklist and IP Whitelist policies are complementary, but different, approaches to limiting access to an API:

  • The IP Blacklist policy type is exclusive in that you must specify the IP address ranges to be excluded from being able to access the API. Any addresses that you do not explicitly exclude from the policy are able to access the API.

  • The IP Whitelist policy type is inclusive in that you must specify the IP address ranges to be included to be able to access the API. Any addresses that you do not explicitly include are not able to access the API.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for an IP Whitelist Policy are:

  • ipList (array) : The IP address(es), and/or ranges of addresses that will be allowed to access the API.

  • responseCode (int) : The server response code. The possible values for the return code are:

    • 500 - Server error

    • 404 - Not found

    • 403 - Authentication failure

  • httpHeader (string) [optional] : Tells Apiman to use the IP address found in the given HTTP request header instead of the one associated with the incoming TCP socket. Useful when going through a proxy, often the value of this is 'X-Forwarded-For'.

Sample Configuration

{
  "ipList" : ["192.168.3.*", "192.168.4.*"],
  "responseCode" : 403,
  "httpHeader" : "X-Forwarded-For"
}

JSONP Policy

Description

This policy turns a standard REST endpoint into a JSONP compatible endpoint. For example, a REST endpoint may typically return the following JSON data:

{
  "foo" : "bar",
  "baz" : 17
}

If the JSONP policy is applied to this API, then the caller must provide a JSONP callback function name via the URL (for details on this, see the Configuration section below). When this is done, the API might respond with this instead:

callbackFunction({
  "foo" : "bar",
  "baz" : 17
})
If the API client does not send the JSONP callback function name in the URL (via the configured query parameter name), this policy will do nothing. This allows managed endpoints to support both standard REST and JSONP at the same time.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-jsonp-policy",
    "version": "1.5.7.Final"
}

Configuration

The JSONP policy has a single configuration property, which can be used to specify the name of the HTTP query parameter that the caller must use to pass the name of the JSONP callback function.

  • callbackParamName (string) : Name of the HTTP query parameter that should contain the JSONP callback function name.

Sample Configuration

{
   "callbackParamName" : "callback"
}

If the above configuration were to be used, the API client (caller) must send the JSONP callback function name in the URL of the request as a query parameter named callback. For example:

GET /path/to/resource?callback=myCallbackFunction HTTP/1.1
Host: www.example.org
Accept: application/json

In this example, the response might look like this:

myCallbackFunction({
  "property1" : "value1",
  "property2" : "value2"
})

JWT Policy

Description

The JWT Policy helps you to validate JWT Tokens by providing a signing key and also via JSON Web Key Set (JWK(S)). You can also require claims and strip them to forward them as header to the backend API.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-jwt-policy",
    "version": "1.5.7.Final"
}

Configuration

Table 5. JWT Policy configuration
Option Type Description Default

requireJwt

Boolean

Require JWT Terminate request if no JWT is provided.

true

requireSigned

Boolean

Require Signed JWT (JWS). Require JWTs be cryptographically signed and verified (JWS). It is strongly recommended to enable this option.

true

requireTransportSecurity

Boolean

Require Transport Security Any request used without transport security will be rejected. JWT requires transport security (e.g. TLS, SSL) to provide protection against a variety of attacks. It is strongly advised this option be switched on.

true

stripTokens

Boolean

Strip tokens Remove any Authorization header or token query parameter before forwarding traffic to the API

true

signingKeyString

String

Signing Key or URL to a JWK(S) To validate JWT. Must be Base-64 encoded or you specify a URL to a JWK(S)

Empty

kid

String

Key ID (kid) of JWK(S) Only set this if you provided a JWK(S) URL. Specify here the kid of the JWK(S).

Empty

allowedClockSkew

Integer

Maximum Clock Skew Maximum allowed clock skew in seconds when validating exp (expiry) and nbf (not before) claims. Zero implies default behaviour.

0

requiredClaims

items[]

Required Claims Set whether to forward roles to an authorization policy.

None

forwardAuthInfo

forwardAuthInfo[]

Forward Claim Information Set auth information from the token into header(s).

None

items

Table 6. Require standard claims, custom claims and ID token fields (case sensitive).
Option Type Description Default

header

String

Claim Fields that the token must contain.

Empty

field

String

Value Value that must match with the value of the claim.

Empty

forwardAuthInfo

Fields from the JWT can be set as headers and forwarded to the API. All standard claims, custom claims and ID token fields are available (case sensitive). A special value of access_token will forward the entire encoded token. Nested claims can be accessed by using javascript dot syntax (e.g: address.country, address.formatted).
Table 7. Forward Keycloak token information
Option Type Description Default

headers

String

Header The header value to set (to paired field).

None

field

String

Field The token field name.

None

Sample Configuration

Example 1 (Signing Key)

{
  "requireJWT": true,
  "requireSigned": false,
  "requireTransportSecurity": true,
  "stripTokens": true,
  "signingKeyString": "Y29uZ3JhdHVsYXRpb25zLCB5b3UgZm91bmQgdGhlIHNlY3JldCByb29tLiB5b3VyIHByaXplIGlzIGEgZnJlZSBkb3dubG9hZCBvZiBhcGltYW4h",
  "allowedClockSkew": 0,
  "requiredClaims": [
    {
      "claimName": "sub",
      "claimValue": "aride"
    }
  ],
  "forwardAuthInfo": [
    {
      "header": "X-Foo",
      "field": "sub"
    }
  ]
}

Example 2 (JWK(S))

{
  "requireJWT": true,
  "requireSigned": true,
  "requireTransportSecurity": true,
  "stripTokens": false,
  "signingKeyString": "http://127.0.0.1:1080/jwks.json",
  "kid": null,
  "allowedClockSkew": 0,
  "requiredClaims": [
    {
      "claimName": "sub",
      "claimValue": "france frichot"
    }
  ]
}

Keycloak OAuth Policy

Description

A Keycloak-specific OAuth2 policy to regulate access to APIs. This plugin enables a wide range of sophisticated auth facilities in combination with, for instance, Keycloak’s federation, brokering and user management capabilities. An exploration of the basics can be found in our blog, but we encourage users to explore the project documentation, as there is a tremendous depth and breadth of functionality, most of which works extremely well with Apiman.

Keycloak’s token format and auth mechanism facilitate excellent performance characteristics, with users able to easily tune the setup to meet their security requirements. In general, this is one of the best approaches for achieving security without greatly impacting performance.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-keycloak-oauth-policy",
    "version": "1.5.7.Final"
}

Configuration

Table 8. Keycloak oauth2 policy configuration
Option Type Description Default

requireOauth

Boolean

Require auth token Terminate request if no OAuth token is provided.

true

requireTransportSecurity

Boolean

Require transport security Any request used without transport security will be rejected. OAuth2 requires transport security (e.g. TLS, SSL) to provide protection against replay attacks. It is strongly advised for this option to be switched on

true

blacklistUnsafeTokens

Boolean

Blacklist unsafe tokens Any tokens used without transport security will be blackedlisted in all gateways to mitigate associated security risks. Uses distributed data store to share blacklist

true

stripTokens

Boolean

Strip tokens Remove any Authorization header or token query parameter before forwarding traffic to the API

true

realm

String

Realm name If you are using KeyCloak 1.2.0x or later this must be a full iss domain path (e.g. mykeycloak.local/auth/realms/apimanrealm); pre-1.2.0x simply use the realm name (e.g. apimanrealm).

Empty

realmCertificateString

String

Keycloak Realm Certificate To validate OAuth2 requests. Must be a PEM-encoded X.509 certificate. This can be copied from the Keycloak console.

Empty

delegateKerberosTicket

Boolean

Delegate Kerberos Ticket Delegate any Kerberos Ticket embedded in the Keycloak token to the API (via the Authorization header).

false

forwardRoles

forwardRoles[]

Forward Keycloak roles Set whether to forward roles to an authorization policy.

None

forwardAuthInfo

forwardAuthInfo[]

Forward auth information Set auth information from the token into header(s).

None

forwardRoles

Table 9. Forward Keycloak roles to the Authorization policy. You should specify your required role(s) in the Authorization policy’s configuration.
Option Type Description Default

active

Boolean

Forward roles Opt whether to forward any type of roles. By default these will be realm roles unless the applicationName option is also provided.

false

applicationName (optional)

String

Application Name Which application roles to forward. Note that you cannot presently forward realm and application roles, only one or the other.

Empty

forwardAuthInfo

Fields from the token can be set as headers and forwarded to the API. All standard claims, custom claims and ID token fields are available (case sensitive). A special value of access_token will forward the entire encoded token. Nested claims can be accessed by using javascript dot syntax (e.g: address.country, address.formatted).
Table 10. Forward Keycloak token information
Option Type Description Default

headers

String

Header The header value to set (to paired field).

None

field

String

Field The token field name.

None

Sample Configuration

{
  "requireOauth": true,
  "requireTransportSecurity": true,
  "blacklistUnsafeTokens": false,
  "stripTokens": false,
  "realm": "apiman-is-cool",
  "realmCertificateString": "Y29uZ3JhdHVsYXRpb25zLCB5b3UgZm91bmQgdGhlIHNlY3JldCByb29tLiB5b3VyIHByaXplIGlzIGEgZnJlZSBkb3dubG9hZCBvZiBhcGltYW4h",
  "forwardRoles": {
    "active": true
  },
  "delegateKerberosTicket": false,
  "forwardAuthInfo": [
    {
      "headers": "X-COUNTRY",
      "field": "address.country"
    },
    {
      "headers": "X-USERNAME",
      "field": "preferred_username"
    }
  ]
}

Log Policy

Description

A policy that logs the headers to standard out. Useful to analyse inbound HTTP traffic to the gateway when added as the first policy in the chain or to analyse outbound HTTP traffic from the gateway when added as the last policy in the chain.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-log-policy",
    "version": "1.5.7.Final"
}

Configuration

The Log Policy can be configured to output the request headers, the response headers, or both. When configuring this policy via the Apiman REST API, there is only property:

  • direction (enum) : Which direction you wish to log, options are: 'request', 'response', 'both'

Sample Configuration

{
   "direction" : "both"
}

Quota Policy

Description

The Quota Policy type performs the same basic functionality as the Rate Limiting policy type, however, the intended use of this policy type is for less fine grained processing (e.g., 10,000 requests per month).

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for a Quota Policy are:

  • limit (integer) : This is the number of requests that must be received before the policy will trigger.

  • granularity (enum) : The Apiman element for which the requests are counted. Valid values are:

    • User

    • Api

    • Client

  • period : The time period over which the policy is applied. Valid values are:

    • Hour

    • Day

    • Month

    • Year

  • headerLimit (string) [optional] : HTTP response header that Apiman will use to store the limit being applied.

  • headerRemaining (string) [optional] : HTTP response header that Apiman will use to store how many requests remain before the limit is reached.

  • headerReset (string) [optional] : HTTP response header that Apiman will use to store the number of seconds until the limit is reset.

Sample Configuration

{
  "limit" : 100000,
  "granularity" : "Client",
  "period" : "Month",
  "headerLimit" : "X-Quota-Limit",
  "headerRemaining" : "X-Quota-Limit-Remaining",
  "headerReset" : "X-Quota-Limit-Reset"
}

Rate Limiting Policy

Description

The Rate Limiting Policy type governs the number of times requests are made to an API within a specified time period. The requests can be filtered by user, application, or API and can set the level of granularity for the time period to second, minute, hour, day, month, or year. The intended use of this policy type is for fine grained processing (e.g., 10 requests per second).

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for a Rate Limiting Policy are:

  • limit (integer) : This is the number of requests that must be received before the policy will trigger. Maximum value is 9007199254740991 (2^53 - 1).

  • granularity (enum) : The Apiman element for which the requests are counted. Valid values are:

    • User

    • Api

    • Client

  • period : The time period over which the policy is applied. Valid values are:

    • Second

    • Minute

    • Hour

    • Day

    • Month

    • Year

  • headerLimit (string) [optional] : HTTP response header that Apiman will use to store the limit being applied.

  • headerRemaining (string) [optional] : HTTP response header that Apiman will use to store how many requests remain before the limit is reached.

  • headerReset (string) [optional] : HTTP response header that Apiman will use to store the number of seconds until the limit is reset.

Sample Configuration

{
  "limit" : 100,
  "granularity" : "Api",
  "period" : "Minute",
  "headerLimit" : "X-Limit",
  "headerRemaining" : "X-Limit-Remaining",
  "headerReset" : "X-Limit-Reset"
}

Simple Header Policy

Description

Set and remove headers on request, response or both. The values can be literal strings, environment, system properties or request headers. Headers can be removed by simple string equality or regular expression.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-simple-header-policy",
    "version": "1.5.7.Final"
}

Configuration

Option Type Description Default

addHeaders

addHeaders[]

Add and overwrite headers Add headers to a request, response or both.

None

stripHeaders

stripHeaders[]

Strip headers Remove headers from a request, response or both when patterns match.

None

addHeaders

Table 11. Add headers
Option Type Description Default

headerName

String

Header Name The name of the header to set.

Empty

headerValue

String

Header Value The value of the header to set, or key into the environment or system properties, depending upon the value of valueType.

Empty

valueType

Enum [String, Env, "System Properties", Header]

Value Type String:: Treat as a literal value. Env:: Treat as a key into the environment Env[headerValue], and set the returned value. System Properties:: Treat as a key into the JVM’s System Properties, and set the returned value. Header:: Treat as key into the http request headers, and set the returned value.

None

applyTo

Enum [Request, Response, Both]

Where to apply rule Request:: Request only. Response:: Response only. Both:: Both request and response.

None

overwrite

Boolean

Overwrite Overwrite any existing header with same name.

false

stripHeaders

Table 12. Strip headers
Option Type Description Default

stripType

Enum[Key, Value]

Strip when Key:: pattern matches key. Value:: pattern matches value.

None

with

Enum[String, Regex]

With matcher type String:: Case-insensitive string equality. Regex:: Case-insensitive regular expression.

Empty

pattern

String

Using pattern String to match or compile into a regex, depending on the value of with.

Empty

Sample Configuration

{
  "addHeaders": [
    {
      "headerName": "X-APIMAN-IS",
      "headerValue": "free-and-open-source",
      "valueType": "String",
      "applyTo": "Response",
      "overwrite": false
    },
    {
      "headerName": "X-LANG-FROM-ENV",
      "headerValue": "LANG",
      "valueType": "Env",
      "applyTo": "Both",
      "overwrite": true
    },
    {
      "headerName": "X-JAVA-VERSION-FROM-PROPS",
      "headerValue": "java.version",
      "valueType": "System Properties",
      "applyTo": "Request",
      "overwrite": false
    },
    {
      "headerName": "X-NEW-HTTP-HEADER",
      "headerValue": "X-OLD-HTTP-HEADER",
      "valueType": "Header",
      "applyTo": "Request",
      "overwrite": false
    }
  ],
  "stripHeaders": [
    {
      "stripType": "Key",
      "with": "String",
      "pattern": "Authorization"
    },
    {
      "stripType": "Key",
      "with": "Regex",
      "pattern": "^password=.*$"
    }
  ]
}

SOAP Authorization Policy

Description

This policy is nearly identical to our Authorization Policy, with the exception that it accepts a SOAPAction in the HTTP header. Please note that this policy will only accept a single SOAPAction header, and will not extract the operation name from the SOAP body.

Plugin

{
	"groupId": "io.apiman.plugins",
	"artifactId": "apiman-plugins-soap-authorization-policy",
	"version": "1.5.7.Final"
}

Configuration

Just as with the Authorization policy, you can define any number of rules you’d like.

  • rules (array) : A single rule that your policy will apply if each of the following properties match:

    • action (string) : Defines the SOAPAction you’d like the policy to be applicable to.

    • role (string) : The role the user must have if this pattern matches the request.

  • multiMatch (boolean) : Should the request pass when any or all of the authorization rules pass? Set to true if all rules must match, false if only one rule must match.

  • requestUnmatched (boolean) : If the request does not match any of the authorization rules, should it pass or fail? Set to true if you want the policy to pass when no rules are matched.

Sample Configuration

{
   "rules" : [
   	{
   		"action": "hello",
   		"role": "admin"
   	},
   	{
   		"action": "goodbye",
   		"role": "user"
   	}
   ],
   "multiMatch": true,
   "requestUnmatched": false
}

Time Restricted Access Policy

Description

This policy is used to only allow access to an API during certain times. In fact, the policy can be configured to apply different time restrictions to different API resources (matched via regular expressions). This allows you to control when client and users are allowed to access your API.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for a Time Restricted Access Policy are:

  • rules (array of objects) : The list of matching rules representing the resources being controlled and the time ranges they are allowed to be accessed.

    • timeStart (time) : Indicates the time of day (UTC) to begin allowing access.

    • timeEnd (time) : Indicates the time of day (UTC) to stop allowing access.

    • dayStart (integer) : Indicates the day of week (1=Monday, 2=Tuesday, etc) to begin allowing access.

    • dayEnd (integer) : Indicates the day of week (1=Monday, 2=Tuesday, etc) to stop allowing access.

    • pathPattern (string regexp) : A regular expression used to match the request’s resource path/destination. The time restriction will be applied only when the request’s resource matches this pattern.

If none of the configured rules matches the request resource path/destination, then no rules will be applied and the request will succeed.

Sample Configuration

{
    "rules": [
        {
            "timeStart": "12:00:00",
            "timeEnd": "20:00:00",
            "dayStart": 1,
            "dayEnd": 5,
            "pathPattern": "/path/to/.*"
        },
        {
            "timeStart": "10:00:00.000Z",
            "timeEnd": "18:00:00.000Z",
            "dayStart": 1,
            "dayEnd": 7,
            "pathPattern": "/other/path/.*"
        }
    ]
}

Transfer Quota Policy

Description

In contrast to the other policy types, Transfer Quota tracks the number of bytes transferred (either uploaded or downloaded) rather than the total number of requests made.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

The configuration parameters for a Quota Policy are:

  • direction (enum) : Indicates whether uploads, downloads, or both directions should count against the limit. Value values are:

    • upload

    • download

    • both

  • limit (integer) : This is the number of requests that must be received before the policy will trigger.

  • granularity (enum) : The Apiman element for which the transmitted bytes are counted. Valid values are:

    • User

    • Api

    • Client

  • period : The time period over which the policy is applied. Valid values are:

    • Hour

    • Day

    • Month

    • Year

  • headerLimit (string) [optional] : HTTP response header that Apiman will use to store the limit being applied.

  • headerRemaining (string) [optional] : HTTP response header that Apiman will use to store how many requests remain before the limit is reached.

  • headerReset (string) [optional] : HTTP response header that Apiman will use to store the number of seconds until the limit is reset.

Sample Configuration

{
  "direction" : "download",
  "limit" : 1024000,
  "granularity" : "Client",
  "period" : "Day",
  "headerLimit" : "X-XferQuota-Limit",
  "headerRemaining" : "X-XferQuota-Limit-Remaining",
  "headerReset" : "X-XferQuota-Limit-Reset"
}

Transformation Policy

Description

This policy converts an API format between JSON and XML. If an API is implemented to return XML, but a client would prefer to receive JSON data, this policy can be used to automatically convert both the request and response bodies. In this way, the client can work with JSON data even though the back-end API requires XML (and responds with XML).

Note that this policy is very generic, and does an automatic conversion between XML and JSON. For more control over the specifics of the format conversion, a custom policy may be a better choice.

Plugin

{
    "groupId": "io.apiman.plugins",
    "artifactId": "apiman-plugins-transformation-policy",
    "version": "1.5.7.Final"
}

Configuration

The configuration of this policy consists of two properties which indicate:

  1. the format required by the client

  2. the format required by the back-end server

From these two properties, the policy can decide how (and if) to convert the data.

  • clientFormat (enum) : The format required by the client, possible values are: 'XML', 'JSON'

  • serverFormat (enum) : The format required by the server, possible values are: 'XML', 'JSON'

Sample Configuration

{
   "clientFormat" : "JSON",
   "serverFormat" : "XML"
}

URL Rewriting Policy

Description

This policy is used to re-write responses from the back-end API such that they will be modified by fixing up any incorrect URLs found with modified ones. This is useful because Apiman works through an API Gateway, and in some cases an API might return URLs to followup action or data endpoints. In these cases the back-end API will likely be configured to return a URL pointing to the unmanaged API endpoint. This policy can fix up those URL references so that they point to the managed API endpoint (the API Gateway endpoint) instead.

This is a built-in policy and therefore no plugins need to be installed prior to using it.

Configuration

This policy requires some basic configuration, including a regular expression used to match the URL, as well as a replacement value.

  • fromRegex (string regex) : A regular expression used to identify a matching URL found in the response.

  • toReplacement (string) : The replacement URL - regular expression groups identified in the fromRegex can be used.

  • processBody (boolean) : Set to true if URLs should be replaced in the response body.

  • processHeaders (boolean) : Set to true if URLs should be replaced in the response headers.

This policy cannot be used for any other replacements besides URLs - the policy is implemented specifically to find and replace valid URLs. As a result, arbitrary regular expression matching will not work (the policy scans for URLs and then matches those URLs against the configured regex). This is done for performance reasons.

Sample Configuration

{
    "fromRegex" : "https?://[^\/]*\/([.\/]*)",
    "toReplacement" : "https://apiman.example.com/$1",
    "processBody" : true,
    "processHeaders" : true

}

URL Whitelist Policy

Description

This policy allows users to explicitly allow only certain API subpaths to be accessed. It’s particularly useful when only a small subset of resources from a back-end API should be exposed through the managed endpoint.

Plugin

{
	"groupId": "io.apiman.plugins",
	"artifactId": "apiman-plugins-url-whitelist-policy",
	"version": "1.5.7.Final"
}

Configuration

Configuration of the URL Whitelist Policy consists of a property to control the stripping of the managed endpoint prefix, and then a list of items representing the endpoint paths that are allowed.

  • removePathPrefix (boolean) : Set to true if you want the managed endpoint prefix to be stripped out before trying to match the request path to the whitelisted items (this is typically set to 'true').

  • whitelist (array of objects) : A list of items, where each item represents an API sub-resource that should be allowed.

    • regex (string) : Regular expression to match the API sub-resource path (e.g. /foo/[0-9]/bar)

    • methodGet (boolean) : True if http GET should be allowed (default false).

    • methodPost (boolean) :True if http POST should be allowed (default false).

    • methodPut (boolean) : True if http PUT should be allowed (default false).

    • methodPatch (boolean) : True if http PATCH should be allowed (default false).

    • methodDelete (boolean) : True if http DELETE should be allowed (default false).

    • methodHead (boolean) : True if http HEAD should be allowed (default false).

    • methodOptions (boolean) : True if http OPTIONS should be allowed (default false).

    • methodTrace (boolean) : True if http TRACE should be allowed (default false).

Sample Configuration

{
    "removePathPrefix" : true,
    "whitelist" : [
        {
            "regex" : "/admin/.*",
            "methodGet" : true,
            "methodPost" : true
        },
        {
            "regex" : "/users/.*",
            "methodGet" : true,
            "methodPost" : true,
            "methodPut" : true,
            "methodDelete" : true
        }
    ]
}