Skip to content

Instantly share code, notes, and snippets.

@volkflo
Last active April 14, 2020 11:04
Show Gist options
  • Save volkflo/0e86cf735c7b03ba0f78de51ebe5af6b to your computer and use it in GitHub Desktop.
Save volkflo/0e86cf735c7b03ba0f78de51ebe5af6b to your computer and use it in GitHub Desktop.
Asciidoc to Markdown

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

  • 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 an additional 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.

Tip

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.

Tip

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

```json { "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.

Tip

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

      • 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:

```json { "realm" : "Example", "forwardIdentityHttpHeader" : "X-Identity", "requireTransportSecurity" : true, "requireBasicAuth" : true, "ldapIdentity" : { "url" : "ldap://example.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:

```json { "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.

Tip

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

Configuration

Important

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

```json { "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 of the originating domain. It is principally a security mechanism to prevent the loading of resources from unexpected domains, for instance via XSS injection attacks.

For further references, see CORS W3C Recommendation 16 January 2014 and MDN’s articles.

Plugin

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-cors-policy", "version": "{{ book.apiman.version.release }}" } ```

Configuration

The configuration options available, are:

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

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

HTTP Security Policy

Description

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

Plugin

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-http-security-policy", "version": "{{ book.apiman.version.release }}" } ```

Configuration

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

section_title

*HTTP Strict Transport Security* Configure HSTS.

None

contentSecurityPolicy

???

*Content Security Policy* CSP definition.

None

hsts

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

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

```json { "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.

Tip

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

```json { "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 the an IP Whitelist policy in the same plan.

Tip

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

```json { "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.

Tip

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

```json { "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:

```json { "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:

```json callbackFunction({ "foo" : "bar", "baz" : 17 }) ```

Tip

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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-jsonp-policy", "version": "{{ book.apiman.version.release }}" } ```

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

```json { "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:

```json 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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-jwt-policy", "version": "{{ book.apiman.version.release }}" } ```

Configuration

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

???[]

*Required Claimss* Set whether to forward roles to an authorization policy.

None

forwardAuthInfo

???[]

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

None

items

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

Tip

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).

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)

```json { "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))

```json { "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 work 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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-keycloak-oauth-policy", "version": "{{ book.apiman.version.release }}" } ```

Configuration

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. `https://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

???[]

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

None

forwardAuthInfo

???[]

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

None

forwardRoles

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

Tip

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).

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

```json { "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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-log-policy", "version": "{{ book.apiman.version.release }}" } ```

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

```json { "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).

Tip

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

```json { "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).

Tip

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

```json { "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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-simple-header-policy", "version": "{{ book.apiman.version.release }}" } ```

Configuration

Option Type Description Default

addHeaders

???[]

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

None

stripHeaders

???[]

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

None

addHeaders

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

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

```json { "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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-soap-authorization-policy", "version": "{{ book.apiman.version.release }}" } ```

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

```json { "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.

Tip

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.

Tip

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

```json { "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.

Tip

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

```json { "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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-transformation-policy", "version": "{{ book.apiman.version.release }}" } ```

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

```json { "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.

Tip

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.

Tip

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

```json { "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

```json { "groupId": "io.apiman.plugins", "artifactId": "apiman-plugins-url-whitelist-policy", "version": "{{ book.apiman.version.release }}" } ```

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

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

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<?asciidoc-toc?>
<?asciidoc-numbered?>
<article lang="en">
<articleinfo>
<title>Apiman Policies</title>
</articleinfo>
<simpara>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.</simpara>
<section id="_policy_types">
<title>Policy Types</title>
<simpara>Apiman supports several policy types like security, limiting, modification and others which are explained in the following.</simpara>
<section id="_security_policies">
<title>Security Policies</title>
<simpara>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.</simpara>
<simpara>Apiman supports these types of security policies:</simpara>
<itemizedlist>
<listitem>
<simpara>
Authorization Policy
</simpara>
</listitem>
<listitem>
<simpara>
BASIC Authentication Policy
</simpara>
</listitem>
<listitem>
<simpara>
CORS Policy
</simpara>
</listitem>
<listitem>
<simpara>
HTTP Security Policy
</simpara>
</listitem>
<listitem>
<simpara>
Ignored Resources Policy
</simpara>
</listitem>
<listitem>
<simpara>
IP Blacklist Policy
</simpara>
</listitem>
<listitem>
<simpara>
IP Whitelist Policy
</simpara>
</listitem>
<listitem>
<simpara>
JWT Policy
</simpara>
</listitem>
<listitem>
<simpara>
Keycloak OAuth Policy
</simpara>
</listitem>
<listitem>
<simpara>
SOAP Authorization Policy
</simpara>
</listitem>
<listitem>
<simpara>
Time Restricted Access Policy
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_limiting_policies">
<title>Limiting Policies</title>
<simpara>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.</simpara>
<simpara>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&#8217;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.</simpara>
<simpara>Each of these policies, if used singly, can be effective in throttling requests.
apiman, however, adds an additional layer of flexibility to your use of these policy types by enabling you to use them in combinations.</simpara>
<simpara>apiman supports these types of limiting policies:</simpara>
<itemizedlist>
<listitem>
<simpara>
Quota Policy
</simpara>
</listitem>
<listitem>
<simpara>
Rate Limiting Policy
</simpara>
</listitem>
<listitem>
<simpara>
Transfer Quota Policy
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_modification_policies">
<title>Modification Policies</title>
<simpara>Apiman supports these types of modification policies:</simpara>
<itemizedlist>
<listitem>
<simpara>
JSONP Policy
</simpara>
</listitem>
<listitem>
<simpara>
Simple Header Policy
</simpara>
</listitem>
<listitem>
<simpara>
URL Rewriting Policy
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_other_policies">
<title>Other Policies</title>
<simpara>Apiman supports these types of other policies:</simpara>
<itemizedlist>
<listitem>
<simpara>
APIKey Policy
</simpara>
</listitem>
<listitem>
<simpara>
Caching Resource Policy
</simpara>
</listitem>
</itemizedlist>
</section>
</section>
<section id="_policies">
<title>Policies</title>
</section>
<section id="_authorization_policy">
<title>Authorization Policy</title>
<section id="policy-authorization">
<title>Description</title>
<simpara>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.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration">
<title>Configuration</title>
<simpara>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.</simpara>
<tip><simpara>It&#8217;s <emphasis role="strong">very</emphasis> important to note that this policy must be configured <emphasis role="strong">after</emphasis> 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&#8217;s roles, which is data that is required for the Authorization Policy to do its work.</simpara></tip>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">rules</emphasis> (array) : Array of rules - each rule is applied only if it matches the current request.
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">pathPattern</emphasis> (string regexp) : Pattern that must match the request resource path you&#8217;d like the policy to be applicable to.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">verb</emphasis> (string) : The HTTP verb that must match the request you&#8217;d like the policy to be applicable to.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">role</emphasis> (string) : The role the user must have if this pattern matches the request.
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">multimatch</emphasis> (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.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">requestUnmatched</emphasis> (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 <emphasis role="strong">pass</emphasis> when no rules are matched.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration">
<title>Sample Configuration</title>
<simpara>```json
{
"rules" : [
{
"pathPattern": "/admin/.<emphasis role="strong">",
"verb": "</emphasis>",
"role": "admin"
},
{
"pathPattern": "/.*",
"verb": "GET",
"role": "user"
}
],
"multiMatch": true,
"requestUnmatched": false
}
```</simpara>
</section>
</section>
<section id="_basic_authentication_policy">
<title>BASIC Authentication Policy</title>
<section id="policy-basic-auth">
<title>Description</title>
<simpara>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.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_2">
<title>Configuration</title>
<simpara>The BASIC Authentication policy has a number of configuration options.
There are several top level configuration properties:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">realm</emphasis> (string) : defines the BASIC Auth realm that will be used when responding with an auth challenge (when authentication is missing or fails)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">forwardIdentityHttpHeader</emphasis> (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)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">requireTransportSecurity</emphasis> (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 <emphasis role="strong">https</emphasis>)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">requireBasicAuth</emphasis> (boolean) : set to true if BASIC authentication credentials are <emphasis role="strong">required</emphasis> (set to false if alternative authentication mechanisms, such as OAuth, are also supported)
</simpara>
</listitem>
</itemizedlist>
<simpara>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.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">jdbcIdentity</emphasis> (object) : included when you wish to use JDBC to connect to a database containing user and password information
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">type</emphasis> (enum) : what type of JDBC connection to use - options are <emphasis>datasource</emphasis>, <emphasis>url</emphasis>
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">datasourcePath</emphasis> (string) : the JNDI path of the datasource to use (only when type is <emphasis>datasource</emphasis>)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">jdbcUrl</emphasis> (string) : the URL to the JDBC database (only when type is <emphasis>url</emphasis>)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">username</emphasis> (string) : the Username to use when connecting to the JDBC database (only when type is <emphasis>url</emphasis>)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">password</emphasis> (string) : the Passowrd to use when connecting to the JDBC database (only when type is <emphasis>url</emphasis>)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">query</emphasis> (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
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">hashAlgorithm</emphasis> (enum) : the hashing algorithm used when storing the password data in the database
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">extractRoles</emphasis> (boolean) : set to true if you also want to extract role information from the database
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">roleQuery</emphasis> (string) : a SQL query to use when extracting role information - the first parameter passed to the query will be the username
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">ldapIdentity</emphasis> (object) : included when you wish to connect to LDAP when validating user credentials
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">url</emphasis> (string) : the URL to the LDAP server
</simpara>
</listitem>
<listitem>
<simpara>
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">bindAs</emphasis> (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&#8217;s record (ServiceAccount)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">credentials</emphasis> (object) : an object with two properties: <emphasis>username</emphasis> and <emphasis>password</emphasis> - credentials used when initially binding to LDAP as a service account
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">userSearch</emphasis> (object) : an object with two properties: <emphasis>baseDn</emphasis> and <emphasis>expression</emphasis> - used to search for the user&#8217;s LDAP record so that it can be used to re-bind to LDAP with the appropriate password
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">extractRoles</emphasis> (boolean) : set to true if you wish to extract role information from LDAP
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">membershipAttribute</emphasis> (string) : the attribute representing the user&#8217;s membership in a group - each value should be a reference to another LDAP node
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">rolenameAttribute</emphasis> (string) : the attribute on a role LDAP node that represents the name of the role
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">staticIdentity</emphasis> (object) : used mostly for testing purposes - allows you to provide a static set of user names and passwords (do not use in production!)
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_ldap">
<title>Sample Configuration (LDAP)</title>
<simpara>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:</simpara>
<simpara>```json
{
"realm" : "Example",
"forwardIdentityHttpHeader" : "X-Identity",
"requireTransportSecurity" : true,
"requireBasicAuth" : true,
"ldapIdentity" : {
"url" : "ldap://example.org",
"bindAs" : "UserAccount",
"extractRoles" : true,
"membershipAttribute" : "memberOf",
"rolenameAttribute" : "objectGUID"
}
}
```</simpara>
</section>
<section id="_sample_configuration_jdbc">
<title>Sample Configuration (JDBC)</title>
<simpara>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:</simpara>
<simpara>```json
{
"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 = ?"
}
}
```</simpara>
</section>
</section>
<section id="_caching_policy_deprecated">
<title>Caching Policy (Deprecated)</title>
<section id="policy-caching">
<title>Description</title>
<simpara>This policy is deprecated. Use <xref linkend="Caching Resources Policy"/> instead.</simpara>
</section>
</section>
<section id="_caching_resources_policy">
<title>Caching Resources Policy</title>
<section id="policy-caching-resources">
<title>Description</title>
<simpara>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.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_3">
<title>Configuration</title>
<important><simpara>If you want to cache POST requests you have to enable stateful request payload inspection in your API Implementation.</simpara></important>
<simpara>The configuration parameters for an Caching Resources Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">ttl</emphasis> (long) : Number of seconds to cache the response.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">cachingResourcesSettingsEntries</emphasis> (array of objects) : The list of matching rules representing the resources to be cached.
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">httpMethod</emphasis> (enum) : The HTTP method to be controlled by the rule. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
* (matches all cachable http methods, see <ulink url="https://developer.mozilla.org/en-US/docs/Glossary/cacheable">https://developer.mozilla.org/en-US/docs/Glossary/cacheable</ulink>)
</simpara>
</listitem>
<listitem>
<simpara>
GET
</simpara>
</listitem>
<listitem>
<simpara>
POST (see important note above)
</simpara>
</listitem>
<listitem>
<simpara>
HEAD
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">pathPattern</emphasis> (string regexp) : A regular expression used to match the REST resource being cached.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">statusCode</emphasis> (string): Either a single number representing a specific status code or * to cache all status codes.
</simpara>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_2">
<title>Sample Configuration</title>
<simpara>```json
{
"ttl" : 60,
"cachingResourcesSettingsEntries" : [
{ "httpMethod" : "GET", "pathPattern" : "/customers", "statusCode" : "200" },
{ "httpMethod" : "POST", "pathPattern" : "/customers/.<emphasis role="strong">/orders", "statusCode": "</emphasis>" },
{ "httpMethod" : "<emphasis role="strong">", "pathPattern" : "/customers/.</emphasis>/orders/bad_debts", "statusCode": "403" }
]
}
```</simpara>
</section>
</section>
<section id="_cors_policy">
<title>CORS Policy</title>
<section id="policy-cors">
<title>Description</title>
<simpara>A policy implementing CORS (Cross-origin resource sharing): a method of defining access to resources outside of the originating domain.
It is principally a security mechanism to prevent the loading of resources from unexpected domains, for instance via XSS injection attacks.</simpara>
<simpara>For further references, see <ulink url="http://www.w3.org/TR/2014/REC-cors-20140116/">CORS W3C Recommendation 16 January 2014</ulink> and <ulink url="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Origin">MDN&#8217;s articles</ulink>.</simpara>
</section>
<section id="_plugin">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-cors-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_4">
<title>Configuration</title>
<simpara>The configuration options available, are:</simpara>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>CORS policy configuration</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>errorOnCorsFailure</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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.</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>allowOrigin</simpara></entry>
<entry align="left" valign="top"><simpara>Set&lt;String&gt;</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>allowCredentials</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Access-Control-Allow-Credentials*
Whether response may be exposed when the `credentials` flag is set to true on the request.</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>exposeHeaders</simpara></entry>
<entry align="left" valign="top"><simpara>Set&lt;String&gt;</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Access-Control-Expose-Headers*
Which non-simple headers the browser may expose during CORS.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>allowHeaders</simpara></entry>
<entry align="left" valign="top"><simpara>Set&lt;String&gt;</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Access-Control-Allow-Headers*
In response to preflight request, which _headers_ can be used during actual request.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>allowMethods</simpara></entry>
<entry align="left" valign="top"><simpara>Set&lt;String&gt;</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Access-Control-Allow-Methods*
In response to preflight request, which _methods_ can be used during actual request.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>maxAge</simpara></entry>
<entry align="left" valign="top"><simpara>Integer</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Access-Control-Max-Age*
How long preflight request can be cached in delta seconds.</literallayout></entry>
<entry align="left" valign="top"><simpara>Not included</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="_sample_configuration_3">
<title>Sample Configuration</title>
<simpara>```json
{
"exposeHeaders" : [
"X-REQUESTS-REMAINING"
],
"maxAge" : 9001,
"allowOrigin" : [
"https://foo.example",
"https://bar.example"
],
"errorOnCorsFailure" : true,
"allowCredentials" : false,
"allowMethods" : [
"POST"
],
"allowHeaders" : [
"X-CUSTOM-HEADER"
]
}
```</simpara>
</section>
</section>
<section id="_http_security_policy">
<title>HTTP Security Policy</title>
<section id="policy-http-security">
<title>Description</title>
<simpara>Security-related HTTP headers can be set, such as HSTS, CSP and XSS protection.</simpara>
</section>
<section id="_plugin_2">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-http-security-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_5">
<title>Configuration</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>HTTP security policy configuration</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>frameOptions</simpara></entry>
<entry align="left" valign="top"><simpara>Enum [DENY, SAMEORIGIN, DISABLED]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Frame Options*
Defines if, or how, a resource should be displayed in a frame, iframe or object.</literallayout></entry>
<entry align="left" valign="top"><simpara>DISABLED</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>xssProtection</simpara></entry>
<entry align="left" valign="top"><simpara>Enum [OFF, ON, BLOCK, DISABLED]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *XSS Protection*
Enable or disable XSS filtering in the UA.</literallayout></entry>
<entry align="left" valign="top"><simpara>DISABLED</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>contentTypeOptions</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *X-Content-Type-Options*
Prevent MIME-sniffing to any type other than the declared Content-Type.</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>hsts</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="_hsts"/></simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *HTTP Strict Transport Security*
Configure HSTS.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>contentSecurityPolicy</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="contentSecurityPolicy"/></simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Content Security Policy*
CSP definition.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
<section id="_hsts">
<title>hsts</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>HTTP Strict Transport Security (hsts): Enforce transport security when using HTTP to mitigate a range of common web vulnerabilities.</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>enabled</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *HSTS*
Enable HTTP Strict Transport</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>includeSubdomains</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><simpara>Include subdomains</simpara></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>maxAge</simpara></entry>
<entry align="left" valign="top"><simpara>Integer</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Maximum age*
Delta seconds user agents should cache HSTS status for</literallayout></entry>
<entry align="left" valign="top"><simpara>0</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>preload</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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.</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="_contentsecuritypolicy">
<title>contentSecurityPolicy</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>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</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>mode</simpara></entry>
<entry align="left" valign="top"><simpara>Enum [ENABLED, REPORT_ONLY, DISABLED]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *CSP Mode*
Which content security policy mode to use.</literallayout></entry>
<entry align="left" valign="top"><simpara>DISABLED</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>csp</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Content Security Policy*
A valid CSP definition to apply</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty string</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="_sample_configuration_4">
<title>Sample Configuration</title>
<simpara>```json
{
"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"
}
```</simpara>
</section>
</section>
<section id="_ignored_resources_policy">
<title>Ignored Resources Policy</title>
<section id="policy-ignored-resources">
<title>Description</title>
<simpara>The ignored resources policy type enables you to shield some of an API&#8217;s resources from being accessed, without blocking access to all the API&#8217;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&#8217;s resources are accessible.</simpara>
<simpara>For example, let&#8217;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:</simpara>
<simpara>/customers
/customers/{customer id}/orders
/customers/{customer id}/orders/bad_debts</simpara>
<simpara>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&#8217;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:</simpara>
<informaltable
frame="all"
rowsep="1" colsep="1"
>
<?dbhtml table-width="80%"?>
<?dbfo table-width="80%"?>
<?dblatex table-width="80%"?>
<tgroup cols="2">
<colspec colname="col_1" colwidth="170*"/>
<colspec colname="col_2" colwidth="170*"/>
<thead>
<row>
<entry align="left" valign="top"> This Path </entry>
<entry align="left" valign="top"> Results in these Resources Being Ignored</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>(empty)</simpara></entry>
<entry align="left" valign="top"><simpara>Access to all resources is allowed</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>/customers</simpara></entry>
<entry align="left" valign="top"><simpara>Denies access to all customer information</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>/customers/.*/orders</simpara></entry>
<entry align="left" valign="top"><simpara>Denies access to all customer order information</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>/customers/.*/orders/bad_debts</simpara></entry>
<entry align="left" valign="top"><simpara>Denies access to all customer bad debt order information</simpara></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<simpara>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.</simpara>
<simpara>The IP-related policy types are less fine-grained in that they allow or block access to all of an API&#8217;s resources based on the IP address of the client application. We&#8217;ll look at these policy types next.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_6">
<title>Configuration</title>
<simpara>The configuration parameters for an Ignored Resources Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">rules</emphasis> (array of objects) : The list of matching rules representing the resources to be ignored.
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">verb</emphasis> (enum) : The HTTP verb to be controlled by the rule. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
* (matches all verbs)
</simpara>
</listitem>
<listitem>
<simpara>
GET
</simpara>
</listitem>
<listitem>
<simpara>
POST
</simpara>
</listitem>
<listitem>
<simpara>
PUT
</simpara>
</listitem>
<listitem>
<simpara>
DELETE
</simpara>
</listitem>
<listitem>
<simpara>
OPTIONS
</simpara>
</listitem>
<listitem>
<simpara>
HEAD
</simpara>
</listitem>
<listitem>
<simpara>
TRACE
</simpara>
</listitem>
<listitem>
<simpara>
CONNECT
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">pathPattern</emphasis> (string regexp) : A regular expression used to match the REST resource being hidden.
</simpara>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_5">
<title>Sample Configuration</title>
<simpara>```json
{
"rules" : [
{ "verb" : "GET", "pathPattern" : "/customers" },
{ "verb" : "POST", "pathPattern" : "/customers/.<emphasis role="strong">/orders" },
{ "verb" : "</emphasis>", "pathPattern" : "/customers/.*/orders/bad_debts"}
]
}
```</simpara>
</section>
</section>
<section id="_ip_blacklist_policy">
<title>IP Blacklist Policy</title>
<section id="policy-ip-blacklist">
<title>Description</title>
<simpara>As its name indicates, the IP blacklist policy type blocks access to an API&#8217;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 the an IP Whitelist policy in the same plan.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_7">
<title>Configuration</title>
<simpara>The configuration parameters for an IP Blacklist Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">ipList</emphasis> (array) : The IP address(es), and/or ranges of addresses that will be blocked from accessing the API.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">responseCode</emphasis> (int) : The server response code. The possible values for the return code are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
500 - Server error
</simpara>
</listitem>
<listitem>
<simpara>
404 - Not found
</simpara>
</listitem>
<listitem>
<simpara>
403 - Authentication failure
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">httpHeader</emphasis> (string) [optional] : Tells apiman to use the IP address found in the given HTTP request header <emphasis role="strong">instead</emphasis> of the one associated with the incoming TCP socket. Useful when going through a proxy, often the value of this is <emphasis>X-Forwarded-For</emphasis>.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_6">
<title>Sample Configuration</title>
<simpara>```json
{
"ipList" : ["192.168.7.*"],
"responseCode" : 500,
"httpHeader" : "X-Forwarded-For"
}
```</simpara>
</section>
</section>
<section id="_ip_whitelist_policy">
<title>IP Whitelist Policy</title>
<section id="policy-ip-whitelist">
<title>Description</title>
<simpara>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.</simpara>
<simpara>The IP Blacklist and IP Whitelist policies are complementary, but different, approaches to limiting access to an API:</simpara>
<itemizedlist>
<listitem>
<simpara>
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.
</simpara>
</listitem>
<listitem>
<simpara>
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.
</simpara>
</listitem>
</itemizedlist>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_8">
<title>Configuration</title>
<simpara>The configuration parameters for an IP Whitelist Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">ipList</emphasis> (array) : The IP address(es), and/or ranges of addresses that will be allowed to access the API.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">responseCode</emphasis> (int) : The server response code. The possible values for the return code are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
500 - Server error
</simpara>
</listitem>
<listitem>
<simpara>
404 - Not found
</simpara>
</listitem>
<listitem>
<simpara>
403 - Authentication failure
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">httpHeader</emphasis> (string) [optional] : Tells apiman to use the IP address found in the given HTTP request header <emphasis role="strong">instead</emphasis> of the one associated with the incoming TCP socket. Useful when going through a proxy, often the value of this is <emphasis>X-Forwarded-For</emphasis>.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_7">
<title>Sample Configuration</title>
<simpara>```json
{
"ipList" : ["192.168.3.<emphasis role="strong">", "192.168.4.</emphasis>"],
"responseCode" : 403,
"httpHeader" : "X-Forwarded-For"
}
```</simpara>
</section>
</section>
<section id="_jsonp_policy">
<title>JSONP Policy</title>
<section id="policy-jsonp">
<title>Description</title>
<simpara>This policy turns a standard REST endpoint into a <ulink url="https://en.wikipedia.org/wiki/JSONP">JSONP</ulink> compatible endpoint.
For example, a REST endpoint may typically return the following JSON data:</simpara>
<simpara>```json
{
"foo" : "bar",
"baz" : 17
}
```</simpara>
<simpara>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 <emphasis role="strong">Configuration</emphasis> section below).
When this is done, the API might respond with this instead:</simpara>
<simpara>```json
callbackFunction({
"foo" : "bar",
"baz" : 17
})
```</simpara>
<tip><simpara>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 <emphasis role="strong">and</emphasis> JSONP at the same time.</simpara></tip>
</section>
<section id="_plugin_3">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-jsonp-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_9">
<title>Configuration</title>
<simpara>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.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">callbackParamName</emphasis> (string) : Name of the HTTP query parameter that should contain the JSONP callback function name.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_8">
<title>Sample Configuration</title>
<simpara>```json
{
"callbackParamName" : "callback"
}
```</simpara>
<simpara>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 <emphasis role="strong">callback</emphasis>.
For example:</simpara>
<simpara>```
GET /path/to/resource?callback=myCallbackFunction HTTP/1.1
Host: www.example.org
Accept: application/json
```</simpara>
<simpara>In this example, the response might look like this:</simpara>
<simpara>```json
myCallbackFunction({
"property1" : "value1",
"property2" : "value2"
})
```</simpara>
</section>
</section>
<section id="_jwt_policy">
<title>JWT Policy</title>
<section id="policy-jwt">
<title>Description</title>
<simpara>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.</simpara>
</section>
<section id="_plugin_4">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-jwt-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_10">
<title>Configuration</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>JWT Policy configuration</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>requireJwt</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Require JWT*
Terminate request if no JWT is provided.</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>requireSigned</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Require Signed JWT (JWS).*
Require JWTs be cryptographically signed and verified (JWS).
It is strongly recommended to enable this option.</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>requireTransportSecurity</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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.</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>stripTokens</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Strip tokens*
Remove any Authorization header or token query parameter before forwarding traffic to the API</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>signingKeyString</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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)</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>kid</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Key ID (kid) of JWK(S)*
Only set this if you provided a JWK(S) URL. Specify here the kid of the JWK(S).</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>allowedClockSkew</simpara></entry>
<entry align="left" valign="top"><simpara>Integer</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Maximum Clock Skew*
Maximum allowed clock skew in seconds when validating exp (expiry) and nbf (not before) claims. Zero implies default behaviour.</literallayout></entry>
<entry align="left" valign="top"><simpara>0</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>requiredClaims</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="items"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Required Claimss*
Set whether to forward roles to an authorization policy.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>forwardAuthInfo</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="forwardAuthInfo"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Forward Claim Information*
Set auth information from the token into header(s).</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
<section id="_items">
<title>items</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Require standard claims, custom claims and ID token fields (case sensitive).</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>header</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Claim*
Fields that the token must contain.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>field</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Value*
Value that must match with the value of the claim.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="_forwardauthinfo">
<title>forwardAuthInfo</title>
<tip><simpara>Fields from the JWT can be set as headers and forwarded to the API. All <ulink url="https://openid.net/specs/openid-connect-basic-1_0.html#StandardClaims">standard claims</ulink>, custom claims and <ulink url="https://openid.net/specs/openid-connect-basic-1_0.html#IDToken">ID token fields</ulink> are available (case sensitive).
A special value of <emphasis role="strong">access_token</emphasis> will forward the entire encoded token. Nested claims can be accessed by using javascript dot syntax (e.g: <literal>address.country</literal>, <literal>address.formatted</literal>).</simpara></tip>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Forward Keycloak token information</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>headers</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Header*
The header value to set (to paired field).</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>field</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Field*
The token field name.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="_sample_configuration_9">
<title>Sample Configuration</title>
<section id="_example_1_signing_key">
<title>Example 1 (Signing Key)</title>
<simpara>```json
{
"requireJWT": true,
"requireSigned": false,
"requireTransportSecurity": true,
"stripTokens": true,
"signingKeyString": "Y29uZ3JhdHVsYXRpb25zLCB5b3UgZm91bmQgdGhlIHNlY3JldCByb29tLiB5b3VyIHByaXplIGlzIGEgZnJlZSBkb3dubG9hZCBvZiBhcGltYW4h",
"allowedClockSkew": 0,
"requiredClaims": [
{
"claimName": "sub",
"claimValue": "aride"
}
],
"forwardAuthInfo": [
{
"header": "X-Foo",
"field": "sub"
}
]
}
```</simpara>
</section>
<section id="_example_2_jwk_s">
<title>Example 2 (JWK(S))</title>
<simpara>```json
{
"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"
}
]
}
```</simpara>
</section>
</section>
</section>
<section id="_keycloak_oauth_policy">
<title>Keycloak OAuth Policy</title>
<section id="policy-keycloak-oauth">
<title>Description</title>
<simpara>A <ulink url="http://www.keycloak.org">Keycloak</ulink>-specific OAuth2 policy to regulate access to APIs.
This plugin enables a wide range of sophisticated auth facilities in combination with, for instance, Keycloak&#8217;s federation, brokering and user management capabilities.
An exploration of the basics can be found <ulink url="http://www.apiman.io/blog/gateway/security/oauth2/keycloak/authentication/authorization/1.2.x/2016/01/22/keycloak-oauth2-redux.html">in our blog</ulink>, but we encourage users to explore the <ulink url="http://keycloak.jboss.org/docs.html">project documentation</ulink>, as there is a tremendous depth and breadth of functionality, most of which work extremely well with apiman.</simpara>
<simpara>Keycloak&#8217;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.</simpara>
</section>
<section id="_plugin_5">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-keycloak-oauth-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_11">
<title>Configuration</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Keycloak oauth2 policy configuration</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>requireOauth</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Require auth token*
Terminate request if no OAuth token is provided.</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>requireTransportSecurity</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>blacklistUnsafeTokens</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>stripTokens</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Strip tokens*
Remove any Authorization header or token query parameter before forwarding traffic to the API</literallayout></entry>
<entry align="left" valign="top"><simpara>true</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>realm</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Realm name*
If you are using KeyCloak 1.2.0x or later this must be a full iss domain path (e.g. `https://mykeycloak.local/auth/realms/apimanrealm`); pre-1.2.0x simply use the realm name (e.g. `apimanrealm`).</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>realmCertificateString</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Keycloak Realm Certificate*
To validate OAuth2 requests.
Must be a PEM-encoded X.509 certificate. This can be copied from the Keycloak console.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>delegateKerberosTicket</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Delegate Kerberos Ticket*
Delegate any Kerberos Ticket embedded in the Keycloak token to the API (via the Authorization header).</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>forwardRoles</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="forwardRoles"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Forward Keycloak roles*
Set whether to forward roles to an authorization policy.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>forwardAuthInfo</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="forwardAuthInfo"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Forward auth information*
Set auth information from the token into header(s).</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
<section id="_forwardroles">
<title>forwardRoles</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Forward Keycloak roles to the Authorization policy. You should specify your required role(s) in the Authorization policy&#8217;s configuration.</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>active</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Forward roles*
Opt whether to forward any type of roles.
By default these will be *realm roles* unless the `applicationName` option is also provided.</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>applicationName (optional)</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Application Name*
Which application roles to forward.
Note that you cannot presently forward realm and application roles, only one or the other.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="_forwardauthinfo_2">
<title>forwardAuthInfo</title>
<tip><simpara>Fields from the token can be set as headers and forwarded to the API. All <ulink url="https://openid.net/specs/openid-connect-basic-1_0.html#StandardClaims">standard claims</ulink>, custom claims and <ulink url="https://openid.net/specs/openid-connect-basic-1_0.html#IDToken">ID token fields</ulink> are available (case sensitive).
A special value of <emphasis role="strong">access_token</emphasis> will forward the entire encoded token. Nested claims can be accessed by using javascript dot syntax (e.g: <literal>address.country</literal>, <literal>address.formatted</literal>).</simpara></tip>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Forward Keycloak token information</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>headers</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Header*
The header value to set (to paired field).</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>field</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Field*
The token field name.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="_sample_configuration_10">
<title>Sample Configuration</title>
<simpara>```json
{
"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"
}
]
}
```</simpara>
</section>
</section>
<section id="_log_policy">
<title>Log Policy</title>
<section id="policy-log">
<title>Description</title>
<simpara>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.</simpara>
</section>
<section id="_plugin_6">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-log-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_12">
<title>Configuration</title>
<simpara>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:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">direction</emphasis> (enum) : Which direction you wish to log, options are: <emphasis>request</emphasis>, <emphasis>response</emphasis>, <emphasis>both</emphasis>
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_11">
<title>Sample Configuration</title>
<simpara>```json
{
"direction" : "both"
}
```</simpara>
</section>
</section>
<section id="_quota_policy">
<title>Quota Policy</title>
<section id="policy-quota">
<title>Description</title>
<simpara>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).</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_13">
<title>Configuration</title>
<simpara>The configuration parameters for a Quota Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">limit</emphasis> (integer) : This is the number of requests that must be received before the policy will trigger.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">granularity</emphasis> (enum) : The apiman element for which the requests are counted. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
User
</simpara>
</listitem>
<listitem>
<simpara>
Api
</simpara>
</listitem>
<listitem>
<simpara>
Client
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">period</emphasis> : The time period over which the policy is applied. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
Hour
</simpara>
</listitem>
<listitem>
<simpara>
Day
</simpara>
</listitem>
<listitem>
<simpara>
Month
</simpara>
</listitem>
<listitem>
<simpara>
Year
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerLimit</emphasis> (string) [optional] : HTTP response header that apiman will use to store the limit being applied.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerRemaining</emphasis> (string) [optional] : HTTP response header that apiman will use to store how many requests remain before the limit is reached.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerReset</emphasis> (string) [optional] : HTTP response header that apiman will use to store the number of seconds until the limit is reset.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_12">
<title>Sample Configuration</title>
<simpara>```json
{
"limit" : 100000,
"granularity" : "Client",
"period" : "Month",
"headerLimit" : "X-Quota-Limit",
"headerRemaining" : "X-Quota-Limit-Remaining",
"headerReset" : "X-Quota-Limit-Reset"
}
```</simpara>
</section>
</section>
<section id="_rate_limiting_policy">
<title>Rate Limiting Policy</title>
<section id="policy-rate-limiting">
<title>Description</title>
<simpara>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).</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_14">
<title>Configuration</title>
<simpara>The configuration parameters for a Rate Limiting Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">limit</emphasis> (integer) : This is the number of requests that must be received before the policy will trigger. Maximum value is 9007199254740991 (2^53 - 1).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">granularity</emphasis> (enum) : The apiman element for which the requests are counted. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
User
</simpara>
</listitem>
<listitem>
<simpara>
Api
</simpara>
</listitem>
<listitem>
<simpara>
Client
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">period</emphasis> : The time period over which the policy is applied. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
Second
</simpara>
</listitem>
<listitem>
<simpara>
Minute
</simpara>
</listitem>
<listitem>
<simpara>
Hour
</simpara>
</listitem>
<listitem>
<simpara>
Day
</simpara>
</listitem>
<listitem>
<simpara>
Month
</simpara>
</listitem>
<listitem>
<simpara>
Year
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerLimit</emphasis> (string) [optional] : HTTP response header that apiman will use to store the limit being applied.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerRemaining</emphasis> (string) [optional] : HTTP response header that apiman will use to store how many requests remain before the limit is reached.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerReset</emphasis> (string) [optional] : HTTP response header that apiman will use to store the number of seconds until the limit is reset.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_13">
<title>Sample Configuration</title>
<simpara>```json
{
"limit" : 100,
"granularity" : "Api",
"period" : "Minute",
"headerLimit" : "X-Limit",
"headerRemaining" : "X-Limit-Remaining",
"headerReset" : "X-Limit-Reset"
}
```</simpara>
</section>
</section>
<section id="_simple_header_policy">
<title>Simple Header Policy</title>
<section id="policy-simple-header">
<title>Description</title>
<simpara>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.</simpara>
</section>
<section id="_plugin_7">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-simple-header-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_15">
<title>Configuration</title>
<informaltable
frame="all"
rowsep="1" colsep="1"
>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>addHeaders</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="addHeaders"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Add and overwrite headers*
Add headers to a request, response or both.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>stripHeaders</simpara></entry>
<entry align="left" valign="top"><simpara><xref linkend="stripHeaders"/>[]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Strip headers*
Remove headers from a request, response or both when patterns match.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<section id="_addheaders">
<title>addHeaders</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Add headers</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>headerName</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Header Name*
The name of the header to set.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>headerValue</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Header Value*
The value of the header to set, or key into the environment or system properties, depending upon the value of `valueType`.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>valueType</simpara></entry>
<entry align="left" valign="top"><simpara>Enum [String, Env, "System Properties", Header]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *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.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>applyTo</simpara></entry>
<entry align="left" valign="top"><simpara>Enum [Request, Response, Both]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Where to apply rule*
Request:: Request only.
Response:: Response only.
Both:: Both request and response.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>overwrite</simpara></entry>
<entry align="left" valign="top"><simpara>Boolean</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Overwrite*
Overwrite any existing header with same name.</literallayout></entry>
<entry align="left" valign="top"><simpara>false</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="_stripheaders">
<title>stripHeaders</title>
<table
frame="all"
rowsep="1" colsep="1"
>
<title>Strip headers</title>
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="12*"/>
<colspec colname="col_3" colwidth="50*"/>
<colspec colname="col_4" colwidth="12*"/>
<thead>
<row>
<entry align="left" valign="top"> Option</entry>
<entry align="left" valign="top"> Type</entry>
<entry align="left" valign="top"> Description</entry>
<entry align="left" valign="top"> Default</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>stripType</simpara></entry>
<entry align="left" valign="top"><simpara>Enum[Key, Value]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Strip when*
Key:: `pattern` matches key.
Value:: `pattern` matches value.</literallayout></entry>
<entry align="left" valign="top"><simpara>None</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>with</simpara></entry>
<entry align="left" valign="top"><simpara>Enum[String, Regex]</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *With matcher type*
String:: Case-insensitive string equality.
Regex:: Case-insensitive regular expression.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>pattern</simpara></entry>
<entry align="left" valign="top"><simpara>String</simpara></entry>
<entry align="left" valign="top"><literallayout class="monospaced"> *Using pattern*
String to match or compile into a regex, depending on the value of `with`.</literallayout></entry>
<entry align="left" valign="top"><simpara>Empty</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="_sample_configuration_14">
<title>Sample Configuration</title>
<simpara>```json
{
"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=.*$"
}
]
}
```</simpara>
</section>
</section>
<section id="_soap_authorization_policy">
<title>SOAP Authorization Policy</title>
<section id="policy-soap-authorization">
<title>Description</title>
<simpara>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.</simpara>
</section>
<section id="_plugin_8">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-soap-authorization-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_16">
<title>Configuration</title>
<simpara>Just as with the Authorization policy, you can define any number of rules you&#8217;d like.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">rules</emphasis> (array) : A single rule that your policy will apply if each of the following properties match:
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">action</emphasis> (string) : Defines the SOAPAction you&#8217;d like the policy to be applicable to.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">role</emphasis> (string) : The role the user must have if this pattern matches the request.
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">multiMatch</emphasis> (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.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">requestUnmatched</emphasis> (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 <emphasis role="strong">pass</emphasis> when no rules are matched.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_15">
<title>Sample Configuration</title>
<simpara>```json
{
"rules" : [
{
"action": "hello",
"role": "admin"
},
{
"action": "goodbye",
"role": "user"
}
],
"multiMatch": true,
"requestUnmatched": false
}
```</simpara>
</section>
</section>
<section id="_time_restricted_access_policy">
<title>Time Restricted Access Policy</title>
<section id="policy-time-restricted-access">
<title>Description</title>
<simpara>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 <emphasis role="strong">when</emphasis> client and users are allowed to access your API.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_17">
<title>Configuration</title>
<simpara>The configuration parameters for a Time Restricted Access Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">rules</emphasis> (array of objects) : The list of matching rules representing the resources being controlled and the time ranges they are allowed to be accessed.
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">timeStart</emphasis> (time) : Indicates the time of day (UTC) to begin allowing access.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">timeEnd</emphasis> (time) : Indicates the time of day (UTC) to stop allowing access.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">dayStart</emphasis> (integer) : Indicates the day of week (1=Monday, 2=Tuesday, etc) to begin allowing access.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">dayEnd</emphasis> (integer) : Indicates the day of week (1=Monday, 2=Tuesday, etc) to stop allowing access.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">pathPattern</emphasis> (string regexp) : A regular expression used to match the request&#8217;s resource path/destination. The time restriction will be applied only when the request&#8217;s resource matches this pattern.
</simpara>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<tip><simpara>If none of the configured rules matches the request resource path/destination, then no rules will be applied and the request will succeed.</simpara></tip>
</section>
<section id="_sample_configuration_16">
<title>Sample Configuration</title>
<simpara>```json
{
"rules": [
{
"timeStart": "12:00:00",
"timeEnd": "20:00:00",
"dayStart": 1,
"dayEnd": 5,
"pathPattern": "/path/to/.<emphasis role="strong">"
},
{
"timeStart": "10:00:00.000Z",
"timeEnd": "18:00:00.000Z",
"dayStart": 1,
"dayEnd": 7,
"pathPattern": "/other/path/.</emphasis>"
}
]
}
```</simpara>
</section>
</section>
<section id="_transfer_quota_policy">
<title>Transfer Quota Policy</title>
<section id="policy-transfer-quota">
<title>Description</title>
<simpara>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.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_18">
<title>Configuration</title>
<simpara>The configuration parameters for a Quota Policy are:</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">direction</emphasis> (enum) : Indicates whether uploads, downloads, or both directions should count against the limit. Value values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
upload
</simpara>
</listitem>
<listitem>
<simpara>
download
</simpara>
</listitem>
<listitem>
<simpara>
both
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">limit</emphasis> (integer) : This is the number of requests that must be received before the policy will trigger.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">granularity</emphasis> (enum) : The apiman element for which the transmitted bytes are counted. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
User
</simpara>
</listitem>
<listitem>
<simpara>
Api
</simpara>
</listitem>
<listitem>
<simpara>
Client
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">period</emphasis> : The time period over which the policy is applied. Valid values are:
</simpara>
<itemizedlist>
<listitem>
<simpara>
Hour
</simpara>
</listitem>
<listitem>
<simpara>
Day
</simpara>
</listitem>
<listitem>
<simpara>
Month
</simpara>
</listitem>
<listitem>
<simpara>
Year
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerLimit</emphasis> (string) [optional] : HTTP response header that apiman will use to store the limit being applied.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerRemaining</emphasis> (string) [optional] : HTTP response header that apiman will use to store how many requests remain before the limit is reached.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">headerReset</emphasis> (string) [optional] : HTTP response header that apiman will use to store the number of seconds until the limit is reset.
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_17">
<title>Sample Configuration</title>
<simpara>```json
{
"direction" : "download",
"limit" : 1024000,
"granularity" : "Client",
"period" : "Day",
"headerLimit" : "X-XferQuota-Limit",
"headerRemaining" : "X-XferQuota-Limit-Remaining",
"headerReset" : "X-XferQuota-Limit-Reset"
}
```</simpara>
</section>
</section>
<section id="_transformation_policy">
<title>Transformation Policy</title>
<section id="policy-transformation">
<title>Description</title>
<simpara>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).</simpara>
<simpara>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.</simpara>
</section>
<section id="_plugin_9">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-transformation-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_19">
<title>Configuration</title>
<simpara>The configuration of this policy consists of two properties which indicate:</simpara>
<orderedlist numeration="arabic">
<listitem>
<simpara>
the format required by the client
</simpara>
</listitem>
<listitem>
<simpara>
the format required by the back-end server
</simpara>
</listitem>
</orderedlist>
<simpara>From these two properties, the policy can decide how (and if) to convert the data.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">clientFormat</emphasis> (enum) : The format required by the client, possible values are: <emphasis>XML</emphasis>, <emphasis>JSON</emphasis>
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">serverFormat</emphasis> (enum) : The format required by the server, possible values are: <emphasis>XML</emphasis>, <emphasis>JSON</emphasis>
</simpara>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_18">
<title>Sample Configuration</title>
<simpara>```json
{
"clientFormat" : "JSON",
"serverFormat" : "XML"
}
```</simpara>
</section>
</section>
<section id="_url_rewriting_policy">
<title>URL Rewriting Policy</title>
<section id="policy-url-rewriting">
<title>Description</title>
<simpara>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.</simpara>
<tip><simpara>This is a built-in policy and therefore no plugins need to be installed prior to using it.</simpara></tip>
</section>
<section id="_configuration_20">
<title>Configuration</title>
<simpara>This policy requires some basic configuration, including a regular expression used to match the URL, as well as a replacement value.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">fromRegex</emphasis> (string regex) : A regular expression used to identify a matching URL found in the response.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">toReplacement</emphasis> (string) : The replacement URL - regular expression groups identified in the <emphasis role="strong">fromRegex</emphasis> can be used.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">processBody</emphasis> (boolean) : Set to true if URLs should be replaced in the response body.
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">processHeaders</emphasis> (boolean) : Set to true if URLs should be replaced in the response headers.
</simpara>
</listitem>
</itemizedlist>
<tip><simpara>This policy <emphasis role="strong">cannot</emphasis> 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.</simpara></tip>
</section>
<section id="_sample_configuration_19">
<title>Sample Configuration</title>
<simpara>```json
{
"fromRegex" : "https?://<emphasis role="strong"><phrase role="^\/">\/([.\/]</phrase></emphasis>)",
"toReplacement" : "https://apiman.example.com/$1",
"processBody" : true,
"processHeaders" : true</simpara>
<simpara>}
```</simpara>
</section>
</section>
<section id="_url_whitelist_policy">
<title>URL Whitelist Policy</title>
<section id="policy-url-whitelist">
<title>Description</title>
<simpara>This policy allows users to explicitly allow only certain API subpaths to be accessed.
It&#8217;s particularly useful when only a small subset of resources from a back-end API should be exposed through the managed endpoint.</simpara>
</section>
<section id="_plugin_10">
<title>Plugin</title>
<simpara>```json
{
"groupId": "io.apiman.plugins",
"artifactId": "apiman-plugins-url-whitelist-policy",
"version": "{{ book.apiman.version.release }}"
}
```</simpara>
</section>
<section id="_configuration_21">
<title>Configuration</title>
<simpara>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.</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">removePathPrefix</emphasis> (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 <emphasis>true</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">whitelist</emphasis> (array of objects) : A list of items, where each item represents an API sub-resource that should be allowed.
</simpara>
<itemizedlist>
<listitem>
<simpara>
<emphasis role="strong">regex</emphasis> (string) : Regular expression to match the API sub-resource path (e.g. /foo/[0-9]/bar)
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodGet</emphasis> (boolean) : True if http GET should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodPost</emphasis> (boolean) :True if http POST should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodPut</emphasis> (boolean) : True if http PUT should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodPatch</emphasis> (boolean) : True if http PATCH should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodDelete</emphasis> (boolean) : True if http DELETE should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodHead</emphasis> (boolean) : True if http HEAD should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodOptions</emphasis> (boolean) : True if http OPTIONS should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
<listitem>
<simpara>
<emphasis role="strong">methodTrace</emphasis> (boolean) : True if http TRACE should be allowed (default <emphasis role="strong">false</emphasis>).
</simpara>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
<section id="_sample_configuration_20">
<title>Sample Configuration</title>
<simpara>```json
{
"removePathPrefix" : true,
"whitelist" : [
{
"regex" : "/admin/.<emphasis role="strong">",
"methodGet" : true,
"methodPost" : true
},
{
"regex" : "/users/.</emphasis>",
"methodGet" : true,
"methodPost" : true,
"methodPut" : true,
"methodDelete" : true
}
]
}
```</simpara>
</section>
</section>
</article>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment