Chapter 6. APIcast Policies

APIcast policies are units of functionality that modify how APIcast operates. Policies can be enabled, disabled, and configured to control how they modify APIcast. Use standard policies provided by Red Hat 3scale.

Control policies for a service with a policy chain. Policy chains do the following:

  • specify what policies APIcast uses
  • provide configuration information for policies 3scale uses
  • specify the order in which 3scale loads policies

6.1. APIcast Standard Policies

Red Hat 3scale provides the following standard policies:

You can enable and configure standard policies in the 3scale API Management.

6.1.1. 3scale Auth Caching policy

The 3scale Auth Caching policy caches authentication calls made to APIcast. You can select an operating mode to configure the cache operations.

3scale Auth Caching is available in the following modes:

1. Strict - Cache only authorized calls.

"Strict" mode only caches authorized calls. If a policy is running under the "strict" mode and if a call fails or is denied, the policy invalidates the cache entry. If the backend becomes unreachable, all cached calls are rejected, regardless of their cached status.

2. Resilient – Authorize according to last request when backend is down.

The "Resilient" mode caches both authorized and denied calls. If the policy is running under the "resilient" mode, failed calls do not invalidate an existing cache entry. If the backend becomes unreachable, calls hitting the cache continue to be authorized or denied based on their cached status.

3. Allow - When backend is down, allow everything unless seen before and denied.

The "Allow" mode caches both authorized and denied calls. If the policy is running under the "allow" mode, cached calls continue to be denied or allowed based on the cached status. However, any new calls are cached as authorized.

Important

Operating in the "allow" mode has security implications. Consider these implications and exercise caution when using the "allow" mode.

4. None - Disable caching.

The "None" mode disables caching. This mode is useful if you want the policy to remain active, but do not want to use caching.

Configuration properties

propertydescriptionvaluesrequired?

caching_type

The caching_type property allows you to define which mode the cache will operate in.

data type: enumerated string [resilient, strict, allow, none]

yes

Policy object example

{
  "name": "caching",
  "version": "builtin",
  "configuration": {
    "caching_type": "allow"
  }
}

For information on how to configure policies, see the Creating a policy chain section of the documentation.

6.1.2. Anonymous Access Policy

The Anonymous access policy exposes a service without authentication. It can be useful, for example, for legacy applications that cannot be adapted to send the authentication parameters. The Anonymous policy only supports services with API Key and App Id / App Key authentication options. When the policy is enabled for API requests that do not have any credentials provided, APIcast will authorize the calls using the default credentials configured in the policy. For the API calls to be authorized, the application with the configured credentials must exist and be active.

Using the Application Plans, you can configure the rate limits on the application used for the default credentials.

Note

You need to place the Anonymous Access policy before the APIcast Policy, when using these two policies together in the policy chain.

Following are the required configuration properties for the policy:

  • auth_type: Select a value from one of the alternatives below and make sure the property corresponds to the authentication option configured for the API:

    • app_id_and_app_key: For App ID / App Key authentication option.
    • user_key: For API key authentication option.
  • app_id (only for app_id_and_app_key auth type): The App Id of the application that will be used for authorization if no credentials are provided with the API call.
  • app_key (only for app_id_and_app_key auth type): The App Key of the application that will be used for authorization if no credentials are provided with the API call.
  • user_key (only for the user_key auth_type): The API Key of the application that will be used for authorization if no credentials are provided with the API call.

Figure 6.1. Anonymous Access Policy

Anonymous Access Policy

6.1.3. CORS Request Handling Policy

The Cross Origin Resource Sharing (CORS) request handling policy allows you to control CORS behavior by allowing you to specify:

  • Allowed headers
  • Allowed methods
  • Allow credentials
  • Allowed origin headers

The CORS request handling policy will block all unspecified CORS requests.

Note

You need to place the CORS Request Handling policy before the APIcast Policy, when using these two policies together in the policy chain.

Configuration properties

propertydescriptionvaluesrequired?

allow_headers

The allow_headers property is an array in which you can specify which CORS headers APIcast will allow.

data type: array of strings, must be a CORS header

no

allow_methods

The allow_methods property is an array in which you can specify which CORS methods APIcast will allow.

data type: array of enumerated strings [GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, CONNECT]

no

allow_origin

The allow_origin property allows you to specify an origin domain APIcast will allow

data type: string

no

allow_credentials

The allow_credentials property allows you to specify whether APIcast will allow a CORS request with credentials

data type: boolean

no

Policy object example

{
  "name": "cors",
  "version": "builtin",
  "configuration": {
    "allow_headers": [
      "App-Id", "App-Key",
      "Content-Type", "Accept"
    ],
    "allow_credentials": true,
    "allow_methods": [
      "GET", "POST"
    ],
    "allow_origin": "https://example.com"
  }
}

For information on how to configure policies, refer to the Creating a policy chain section of the documentation.

6.1.4. Echo Policy

The echo policy prints an incoming request back to the client, along with an optional HTTP status code.

Configuration properties

propertydescriptionvaluesrequired?

status

The HTTP status code the echo policy will return to the client

data type: integer

no

exit

Specifies which exit mode the echo policy will use. The request exit mode stops the incoming request from being processed. The set exit mode skips the rewrite phase.

data type: enumerated string [request, set]

yes

Policy object example

{
  "name": "echo",
  "version": "builtin",
  "configuration": {
    "status": 404,
    "exit": "request"
  }
}

For information on how to configure policies, refer to the Creating a policy chain section of the documentation.

6.1.5. Header Modification Policy

The Header modification policy allows you to modify the existing headers or define additional headers to add to or remove from an incoming request or response. You can modify both response and request headers.

The Header modification policy supports the following configuration parameters:

  • request: List of operations to apply to the request headers
  • response: List of operations to apply to the response headers

Each operation consists of the following parameters:

  • op: Specifies the operation to be applied. The add operation adds a value to an existing header. The set operation creates a header and value, and will overwrite an existing header’s value if one already exists. The push operation creates a header and value, but will not overwrite an existing header’s value if one already exists. Instead, push will add the value to the existing header. The delete operation removes the header.
  • header: Specifies the header to be created or modified and can be any string that can be used as a header name (e.g. Custom-Header).
  • value_type: Defines how the header value will be evaluated and can either be plain for plain text or liquid for evaluation as a Liquid template. For more information, see Section 6.4, “Using variables and filters in policies”.
  • value: Specifies the value that will be used for the header. For value type "liquid" the value should be in the format {{ variable_from_context }}. Not needed when deleting.

Policy object example

{
  "name": "headers",
  "version": "builtin",
  "configuration": {
    "response": [
      {
        "op": "add",
        "header": "Custom-Header",
        "value_type": "plain",
        "value": "any-value"
      }
    ],
    "request": [
      {
        "op": "set",
        "header": "Authorization",
        "value_type": "plain",
        "value": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
      },
      {
        "op": "set",
        "header": "Service-ID",
        "value_type": "liquid",
        "value": "{{service.id}}"
      }
    ]
  }
}

For information on how to configure policies, see the Creating a policy chain section of the documentation.

6.1.6. IP Check Policy

The IP check policy is used to deny or allow requests based on a list of IPs.

Configuration properties

propertydescriptiondata typerequired?

check_type

The check_type property has two possible values, whitelist or blacklist. blacklist will deny all requests from IPs on the list. whitelist will deny all requests from IPs not on the list.

string, must be either whitelist or blacklist

yes

ips

The ips property allows you to specify a list of IP addresses to whitelist or blacklist. Both single IPs and CIDR ranges can be used.

array of strings, must be valid IP addresses

yes

error_msg

The error_msg property allows you to configure the error message returned when a request is denied.

string

no

client_ip_sources

The client_ip_sources property allows you to configure how to retrieve the client IP. By default, the last caller IP is used. The other options are X-Forwarded-For and X-Real-IP.

array of strings, valid options are one or more of X-Forwarded-For, X-Real-IP, last_caller.

no

Policy object example

{
  "name": "ip_check",
  "configuration": {
    "ips": [ "3.4.5.6", "1.2.3.0/4" ],
    "check_type": "blacklist",
    "client_ip_sources": ["X-Forwarded-For", "X-Real-IP", "last_caller"],
    "error_msg": "A custom error message"
  }
}

For information on how to configure policies, refer to the Creating a policy chain section of the documentation.

6.1.7. Liquid Context Debug Policy

Note

The Liquid Context Debug policy is meant only for debugging purposes in the development environment and not in production.

This policy responds to the API request with a JSON, containing the objects and values that are available in the context and can be used for evaluating Liquid templates. When combined with the 3scale APIcast or Upstream policy, Liquid Context Debug must be placed before them in the policy chain in order to work correctly. To avoid circular references, the policy only includes duplicated objects once and replaces them with a stub value.

An example of the value returned by APIcast when the policy is enabled:

{
  "jwt": {
    "azp": "972f7b4f",
    "iat": 1537538097,
    ...
    "exp": 1537574096,
    "typ": "Bearer"
  },
  "credentials": {
    "app_id": "972f7b4f"
  },
  "usage": {
    "deltas": {
      "hits": 1
    },
    "metrics": [
      "hits"
    ]
  },
  "service": {
    "id": "2",
    ...
  }
  ...
}

6.1.8. Referrer Policy

The Referrer policy enables the Referrer Filtering feature. When the policy is enabled in the service policy chain, APIcast sends the value of the Referer policy of the upcoming request to the Service Management API (AuthRep call) in the referrer parameter. For more information on how Referrer Filtering works, see the Referrer Filtering section in Authentication Patterns.

6.1.9. RH-SSO/Keycloak Role Check Policy

This policy adds role check when used with the OpenID Connect authentication option. This policy verifies realm roles and client roles in the access token issued by Red Hat Single Sign-On. The realm roles are specified when you want to add role check to every client’s resources or 3Scale.

Following are the two types of role checks that the type property specifies in the policy configuration:

  • whitelist (default): When whitelist is used, APIcast will check if the specified scopes are present in the JWT token and will reject the call if the JWT doesn’t have the scopes.
  • blacklist: When blacklist is used, APIcast will reject the calls if the JWT token contains the blacklisted scopes.

It is not possible to configure both checks – blacklist and whitelist in the same policy, but you can add more than one instances of the RH-SSO/Keycloak role check policy to the APIcast policy chain.

You can configure a list of scopes via the scopes property of the policy configuration.

Each scope object has the following properties:

  • resource: Resource (endpoint) controlled by the role. This is the same format as Mapping Rules. The pattern matches from the beginning of the string and to make an exact match you must append $ at the end.
  • resource_type: This defines how the resource value is evaluated.

    • As plain text (plain): Evaluates the resource value as plain text. Example: /api/v1/products$.
    • As Liquid text (liquid): Allows using Liquid in the resource value. Example: /resource_{{ jwt.aud }} manages access to the resource including the Client ID (contained in the JWT aud claim).
  • realm_roles: Use it to check the realm role (see the Realm Roles in Red Hat Single Sign-On documentation).

    The realm roles are present in the JWT issued by Red Hat Single Sign-On.

      "realm_access": {
        "roles": [
          "<realm_role_A>", "<realm_role_B>"
        ]
      }

    The real roles must be specified in the policy.

    "realm_roles": [
      { "name": "<realm_role_A>" }, { "name": "<realm_role_B>" }
    ]

    Following are the available properties of each object in the realm_roles array:

  • name: Specifies the name of the role.
  • name_type: Defines how the name must be evaluated; it can be plain or liquid (works the same way as for the resource_type).
  • client_roles: Use client_roles to check for the particular access roles in the client namespace (see the Client Roles in Red Hat Single Sign-On documentation).

    The client roles are present in the JWT under the resource_access claim.

      "resource_access": {
        "<client_A>": {
          "roles": [
            "<client_role_A>", "<client_role_B>"
          ]
        },
        "<client_B>": {
          "roles": [
            "<client_role_A>", "<client_role_B>"
          ]
        }
      }

    Specify the client roles in the policy.

    "client_roles": [
      { "name": "<client_role_A>", "client": "<client_A>" },
      { "name": "<client_role_B>", "client": "<client_A>" },
      { "name": "<client_role_A>", "client": "<client_B>" },
      { "name": "<client_role_B>", "client": "<client_B>" }
    ]

    Following are the available properties of each object in the client_roles array:

  • name: Specifies the name of the role.
  • name_type: Defines how the name value must be evaluated; it can be plain or liquid (works the same way as for the resource_type).
  • client: Specifies the client of the role. When it is not defined, this policy uses the aud claim as the client.
  • client_type: Defines how the client value must be evaluated; it can be plain or liquid (works the same way as for the resource_type).

6.1.10. Routing Policy

The Routing policy allows you to route requests to different target endpoints. You can define target endpoints and then you will be able to route incoming requests from the UI to those using regular expressions.

When combined with the APIcast policy, the Routing policy should be placed before the APIcast one in the chain, as the two policies that comes first will output content to the response. When the second gets a change to run its content phase, the request will already be sent to the client, so it will not output anything to the response.

6.1.10.1. Routing rules

  • If multiple rules exist, it will apply the first match. The rules will be ordered.
  • If no rules apply, it will apply upstream, so the policy will work in combination with APIcast policy, which gets the upstream from the service config, which is a private base URL.

6.1.10.2. Request path rule

This is a configuration that routes to http://example.com when the path is /accounts:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/accounts"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.3. Header rule

This is a configuration that routes to http://example.com when the value of the header Test-Header is 123:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "header",
               "header_name": "Test-Header",
               "op": "==",
               "value": "123"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.4. Query argument rule

This is a configuration that routes to http://example.com when the value of the query argument test_query_arg is 123:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "query_arg",
               "query_arg_name": "test_query_arg",
               "op": "==",
               "value": "123"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.5. JWT claim rule

To route based on the value of a JWT claim, there needs to be a policy in the chain that validates the JWT and stores it in the context that the policies share.

This is a configuration that routes to http://example.com when the value of the JWT claim test_claim is 123:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "jwt_claim",
               "jwt_claim_name": "test_claim",
               "op": "==",
               "value": "123"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.6. Multiple operations rule

Rules can have multiple operations and route to the given upstream only when all of them evaluate to true (using the 'and' combine_op), or when at least one of them evaluates to true (using the 'or' combine_op). The default value of combine_op is 'and'.

This is a configuration that routes to http://example.com when the path of the request is /accounts and when the value of the header Test-Header is 123:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "combine_op": "and",
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/accounts"
             },
             {
               "match": "header",
               "header_name": "Test-Header",
               "op": "==",
               "value": "123"
             }
           ]
         }
       }
     ]
   }
 }

This is a configuration that routes to http://example.com when the path of the request is /accounts or when the value of the header Test-Header is 123:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "combine_op": "or",
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/accounts"
             },
             {
               "match": "header",
               "header_name": "Test-Header",
               "op": "==",
               "value": "123"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.7. Combining rules

Rules can be combined. When there are several rules, the upstream selected is one of the first rules that evaluates to true.

This is a configuration with several rules:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://some_upstream.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/accounts"
             }
           ]
         }
       },
       {
         "url": "http://another_upstream.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/users"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.8. Catch-all rules

A rule without operations always matches. This can be useful to define catch-all rules.

This configuration routes the request to http://some_upstream.com if the path is /abc, routes the request to http://another_upstream.com if the path is /def, and finally, routes the request to http://default_upstream.com if none of the previous rules evaluated to true:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://some_upstream.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/abc"
             }
           ]
         }
       },
       {
         "url": "http://another_upstream.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/def"
             }
           ]
         }
       },
       {
         "url": "http://default_upstream.com",
         "condition": {
           "operations": []
         }
       }
     ]
   }
 }

6.1.10.9. Supported operations

The supported operations are ==, !=, and matches. The latter matches a string with a regular expression and it is implemented using ngx.re.match

This is a configuration that uses !=. It routes to http://example.com when the path is not /accounts:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "!=",
               "value": "/accounts"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.10. Liquid templating

It is possible to use liquid templating for the values of the configuration. This allows you to define rules with dynamic values if a policy in the chain stores the key my_var in the context.

This is a configuration that uses that value to route the request:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "condition": {
           "operations": [
             {
               "match": "header",
               "header_name": "Test-Header",
               "op": "==",
               "value": "{{ my_var }}",
               "value_type": "liquid"
             }
           ]
         }
       }
     ]
   }
 }

6.1.10.11. Set the host used in the Host header

By default, when a request is routed, the policy sets the Host header using the host of the URL of the rule that matched. It is possible to specify a different host with the host_header attribute.

This is a configuration that specifies some_host.com as the host of the Host header:

{
   "name": "routing",
   "version": "builtin",
   "configuration": {
     "rules": [
       {
         "url": "http://example.com",
         "host_header": "some_host.com",
         "condition": {
           "operations": [
             {
               "match": "path",
               "op": "==",
               "value": "/"
             }
           ]
         }
       }
     ]
   }
 }

6.1.11. SOAP Policy

The SOAP policy matches SOAP action URIs provided in the SOAPAction or Content-Type header of an HTTP request with mapping rules specified in the policy.

Configuration properties

propertydescriptionvaluesrequired?

pattern

The pattern property allows you to specify a string that APIcast will seek matches for in the SOAPAction URI.

data type: string

yes

metric_system_name

The metric_system_name property allows you to specify the 3scale backend metric with which your matched pattern will register a hit.

data type: string, must be a valid metric

yes

Policy object example

{
  "name": "soap",
  "version": "builtin",
  "configuration": {
    "mapping_rules": [
      {
        "pattern": "http://example.com/soap#request",
        "metric_system_name": "soap",
        "delta": 1
      }
    ]
  }
}

For information on how to configure policies, refer to the Creating a policy chain section of the documentation.

6.1.12. TLS Client Certificate Validation Policy

6.1.12.1. About TLS Client Certificate Validation policy

With the TLS Client Certificate Validation policy, APIcast implements a TLS handshake and validates the client certificate against a whitelist. A whitelist contains certificates signed by the Certified Authority (CA) or just plain client certificates. In case of an expired or invalid certificate, the request is rejected and no other policies will be processed.

The client connects to APIcast to send a request and provides a Client Certificate. APIcast verifies the authenticity of the provided certificate in the incoming request according to the policy configuration. APIcast can also be configured to use a client certificate of its own to use it when connecting to the upstream.

6.1.12.2. Setting up APIcast to work with TLS Client Certificate Validation

APIcast needs to be configured to terminate TLS. Follow the steps below to configure the validation of client certificates provided by users on APIcast with the Client Certificate Validation policy.

6.1.12.2.1. Prerequisites:
  • You need to have access to a 3scale installation.
  • You need to wait for all the deployments to finish.
6.1.12.2.2. Setting up APIcast to work with the policy

To set up APIcast and configure it to terminate TLS, follow these steps:

  1. You need to get the access token and deploy APIcast self-managed, as indicated in Deploy APIcast using the OpenShift template.

    Note

    APIcast self-managed deployment is required as the APIcast instance needs to be reconfigured to use some certificates for the whole gateway.

  2. For testing purposes only, you can use the lazy loader with no cache and staging environment and --param flags for the ease of testing

    oc new-app -f https://raw.githubusercontent.com/3scale/3scale-amp-openshift-templates/master/apicast-gateway/apicast.yml --param CONFIGURATION_LOADER=lazy --param DEPLOYMENT_ENVIRONMENT=staging --param CONFIGURATION_CACHE=0
  3. Generate certificates for testing purposes. Alternatively, for production deployment, you can use the certificates provided by a Certificate Authority.
  4. Create a Secret with TLS certificates

    oc create secret tls apicast-tls
    --cert=ca/certs/server.crt
    --key=ca/keys/server.key
  5. Mount the Secret inside the APIcast deployment

    oc set volume dc/apicast --add --name=certificates --mount-path=/var/run/secrets/apicast --secret-name=apicast-tls
  6. Configure APIcast to start listening on port 8443 for HTTPS

    oc set env dc/apicast APICAST_HTTPS_PORT=8443 APICAST_HTTPS_CERTIFICATE=/var/run/secrets/apicast/tls.crt APICAST_HTTPS_CERTIFICATE_KEY=/var/run/secrets/apicast/tls.key
  7. Expose 8443 on the Service

    oc patch service apicast -p '{"spec":{"ports":[{"name":"https","port":8443,"protocol":"TCP"}]}}'
  8. Delete the default route

    oc delete route api-apicast-staging
  9. Expose the apicast service as a route

    oc create route passthrough --service=apicast --port=https --hostname=api-3scale-apicast-staging.$WILDCARD_DOMAIN
    Note

    This step is needed for every API you are going to use and the domain changes for every API.

  10. Verify that the previously deployed gateway works and the configuration was saved, by specifying [Your_user_key] in the placeholder.

    curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN?user_key=[Your_user_key] -v --cacert ca/certs/ca.crt

6.1.12.3. Configuring TLS Client Certificate Validation in your policy chain

6.1.12.3.1. Prerequisites
6.1.12.3.2. Configuring the policy
  1. To add the TLS Client Certificate Validation policy to your API, follow the steps described in Enabling a standard Policy and choose TLS Client Certificate Validation.
  2. Click the TLS Client Certificate Validation link.
  3. To enable the policy, select the Enabled checkbox.
  4. To add certificates to the whitelist, click the plus + icon.
  5. Specify the certificate including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----.
  6. When you have finished setting up your API with TLS Client Certificate Validation, click Update Policy.

Additionally:

  • You can add more certificates by clicking the plus + icon.
  • You can also reorganize the certificates by clicking the up and down arrows.

To save your changes, click Update & test in Staging Environment.

6.1.12.4. Verifying functionality of the TLS Client Certificate Validation policy

6.1.12.4.1. Prerequisites:
6.1.12.4.2. Verifying policy functionality

You can verify the applied policy by specifying [Your_user_key] in the placeholder.

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt --cert ca/certs/client.crt --key ca/keys/client.key

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt --cert ca/certs/server.crt --key ca/keys/server.key

curl https://api-3scale-apicast-staging.$WILDCARD_DOMAIN\?user_key\=[Your_user_key] -v --cacert ca/certs/ca.crt

6.1.12.5. Removing a certificate from the whitelist

6.1.12.5.1. Prerequisites
6.1.12.5.2. Removing a certificate
  1. Click the TLS Client Certificate Validation link.
  2. To remove certificates from the whitelist, click the x icon.
  3. When you have finished removing the certificates, click Update Policy.

To save your changes, click Update & test in Staging Environment.

6.1.12.6. Reference material

For more information about working with certificates, you can refer to Red Hat Certificate System.

6.1.13. Upstream Policy

The Upstream policy allows you to parse the Host request header using regular expressions and replace the upstream URL defined in the Private Base URL with a different URL.

For Example:

A policy with a regex /foo, and URL field newexample.com would replace the URL https://www.example.com/foo/123/ with newexample.com

Policy chain reference:

propertydescriptionvaluesrequired?

regex

The regex property allows you to specify the regular expression that the Upstream policy will use when searching for a match with the request path.

data type: string, Must be a valid regular expression syntax

yes

url

Using the url property, you can specify the replacement URL in the event of a match. Note that the upstream policy does not check whether or not this URL is valid.

data type: string, ensure this is a valid URL

yes

Policy object example

{
  "name": "upstream",
  "version": "builtin",
  "configuration": {
    "rules": [
      {
        "regex": "^/v1/.*",
        "url": "https://api-v1.example.com",

      }
    ]
  }
}

For information on how to configure policies, refer to the Creating a policy chain section of the documentation.

6.1.14. URL Rewriting Policy

The URL rewriting policy allows you to modify the path of a request and the query string.

When combined with the 3scale APIcast policy, if the URL rewriting policy is placed before the 3scale APIcast policy in the policy chain, the APIcast mapping rules will apply to the modified path. If the URL rewriting policy is placed after APIcast in the policy chain, then the mapping rules will apply to the original path.

The policy supports the following two sets of operations:

  • commands: List of commands to be applied to rewrite the path of the request.
  • query_args_commands: List of commands to be applied to rewrite the query string of the request.

6.1.14.1. Commands for rewriting the path

Following are the configuration parameters that each command in the commands list consists of:

  • op: Operation to be applied. The options available are: sub and gsub. The sub operation replaces only the first occurrence of a match with your specified regular expression. The gsub operation replaces all occurrences of a match with your specified regular expression. See the documentation for the sub and gsub operations.
  • regex: Perl-compatible regular expression to be matched.
  • replace: Replacement string that is used in the event of a match.
  • options (optional): Options that define how the regex matching is performed. For information on available options, see the ngx.re.match section of the OpenResty Lua module project documentation.
  • break (optional): When set to true (checkbox enabled), if the command rewrote the URL, it will be the last one applied (all posterior commands in the list will be discarded).

6.1.14.2. Commands for rewriting the query string

Following are configuration parameters that each command in the query_args_commands list consists of:

  • op: Operation to be applied to the query arguments. The following options are available:

    • add: Add a value to an existing argument.
    • set: Create the arg when not set and replace its value when set.
    • push: Create the arg when not set and add the value when set.
    • delete: Delete an arg.
  • arg: The query argument name that the operation is applied on.
  • value: Specifies the value that is used for the query argument. For value type "liquid" the value should be in the format {{ variable_from_context }}. For the delete operation the value is not taken into account.
  • value_type (optional): Defines how the query argument value is evaluated and can either be plain for plain text or liquid for evaluation as a Liquid template. For more information, see Section 6.4, “Using variables and filters in policies”. If not specified, the type "plain" is used by default.

Example

The URL Rewriting policy is configured as follows:

{
  "name": "url_rewriting",
  "version": "builtin",
  "configuration": {
    "query_args_commands": [
      {
        "op": "add",
        "arg": "addarg",
        "value_type": "plain",
        "value": "addvalue"
      },
      {
        "op": "delete",
        "arg": "user_key",
        "value_type": "plain",
        "value": "any"
      },
      {
        "op": "push",
        "arg": "pusharg",
        "value_type": "plain",
        "value": "pushvalue"
      },
      {
        "op": "set",
        "arg": "setarg",
        "value_type": "plain",
        "value": "setvalue"
      }
    ],
    "commands": [
      {
        "op": "sub",
        "regex": "^/api/v\\d+/",
        "replace": "/internal/",
        "options": "i"
      }
    ]
  }

The original request URI that is sent to the APIcast:

https://api.example.com/api/v1/products/123/details?user_key=abc123secret&pusharg=first&setarg=original

The URI that APIcast sends to the API backend after applying the URL rewriting:

https://api-backend.example.com/internal/products/123/details?pusharg=first&pusharg=pushvalue&setarg=setvalue

The following transformations are applied:

  1. The substring /api/v1/ matches the only path rewriting command and it is replaced by /internal/.
  2. user_key query argument is deleted.
  3. The value pushvalue is added as an additional value to the pusharg query argument.
  4. The value original of the query argument setarg is replaced with the configured value setvalue.
  5. The command add was not applied because the query argument addarg is not present in the original URL.

For information on how to configure policies, see the Creating a policy chain section of the documentation.

6.1.15. URL Rewriting with Captures Policy

The URL Rewriting with Captures policy is an alternative to the Section 6.1.14, “URL Rewriting Policy” policy and allows rewriting the URL of the API request before passing it to the API backend.

The URL Rewriting with Captures policy captures arguments in the URL and uses their values in the rewritten URL.

The policy supports the transformations configuration parameter. It is a list of objects that describe which transformations are applied to the request URL. Each tranformation object consist of two properties:

  • match_rule: This rule is matched to the incoming request URL. It can contain named arguments in the {nameOfArgument} format; these arguments can be used in the rewritten URL. The URL is compared to match_rule as a regular expression. The value that matches named arguments must contain only the following characters (in PCRE regex notation): [\w-.~%!$&'()*,;=@:]. Other regex tokens can be used in the match_rule expression, such as ^ for the beginning of the string and $ for the end of the string.
  • template: The template for the URL that the original URL is rewritten with; it can use named arguments from the match_rule.

The query parameters of the original URL are merged with the query parameters specified in the template.

Example

The URL Rewriting with Captures is configured as follows:

{
  "name": "rewrite_url_captures",
  "version": "builtin",
  "configuration": {
    "transformations": [
      {
        "match_rule": "/api/v1/products/{productId}/details",
        "template": "/internal/products/details?id={productId}&extraparam=anyvalue"
      }
    ]
  }
}

The original request URI that is sent to the APIcast:

https://api.example.com/api/v1/products/123/details?user_key=abc123secret

The URI that APIcast sends to the API backend after applying the URL rewriting:

https://api-backend.example.com/internal/products/details?user_key=abc123secret&extraparam=anyvalue&id=123

6.2. Enabling a standard policy

Perform the following steps to enable policies in the Admin Portal:

  1. Log in to 3scale.
  2. Navigate to the API service.
  3. From [your_API_name] > Integration > Configuration, select edit APIcast configuration.
  4. Under the POLICIES section, click add policy.
  5. Select the policy you want to add and fill out the required fields.
  6. Click the Update and test in Staging Environment button to save the policy chain.

6.3. Creating a policy chain in the AMP

Create a policy chain in the AMP as part of your APIcast gateway configuration. Follow these steps to modify the policy chain in the UI:

  1. Log in to your AMP
  2. Navigate to the API service

    navigate to APIcast integrations page
  3. From [your_API_name] > Integration > Configuration, select edit APIcast configuration

    navigate to APIcast configuration page
  4. Under the POLICIES section, use the arrow icons to reorder policies in the policy chain. Always place the APIcast policy last in the policy chain.

    policyChainOverview
  5. Click the Update and test in Staging Environment button to save the policy chain

6.4. Using variables and filters in policies

Some Section 6.1, “APIcast Standard Policies” support Liquid templating that allows using not only plain string values, but also variables that are present in the context of the request.

To use a context variable, wrap its name in {{ and }}, example: {{ uri }}. If the variable is an object, you can also access its attributes, for example: {{ somevar.attr }}.

Following are the standard variables that are available in all the policies:

  • uri: The path of the request without query parameters (the value of the embedded NGINX variable $uri).
  • host: The host of the request (the value of the embedded NGINX variable $host).
  • remote_addr: The IP address of the client (the value of the embedded NGINX variable $remote_addr).
  • headers: The object containing the request headers. Use {{headers['Some-Header']}} to get a specific header value.
  • http_method: The request method: GET, POST, etc.

The variables are available in the context of the request. Policies can add extra variables to the context. These variables can be used by the same or other policies in the policy chain, provided that the phase where they are used is executed after the phase where the variable was added. It can also be the same phase if the variable is used in the policy that appears after the policy in which the variable was added.

Following are some examples of variables that the standard 3scale APIcast policy adds to the context:

  • jwt: A parsed JSON payload of the JWT token (for OpenID Connect authentication).
  • credentials: An object that holds the application credentials. Example: "app_id": "972f7b4f", "user_key": "13b668c4d1e10eaebaa5144b4749713f".
  • service: An object that holds the configuration for the service that the current request is handled by. Example: the service ID would be available as {{ service.id }}.

For a full list of objects and values available in the context, see the Section 6.1.7, “Liquid Context Debug Policy”).

The variables are used with the help of Liquid templates. Example: {{ remote_addr }}, {{ headers['Some-Header'] }}, {{ jwt.aud }}. The policies that support variables for the values have a special parameter, usually with the _type suffix (example: value_type, name_type, etc.) that accepts two values: "plain" for plain text and "liquid" for liquid template.

APIcast also supports Liquid filters that can be applied to the variables' values. The filters apply NGINX functions to the value of the Liquid variable.

The filters are placed within the variable output tag {{ }}, following the name of the variable or the literal value by a pipe character | and the name of the filter. Examples: {{ 'username:password' | encode_base64 }}, {{ uri | escape_uri }}.

Some filters do not require parameters, so you can use an empty string instead of the variable. Example: {{ '' | utctime }} will return the current time in UTC time zone.

Filters can be chained as follows: {{ variable | function1 | function2 }}. Example: {{ '' | utctime | escape_uri }}.

Following is the list of the available functions: