Chapter 4. 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 policies to add functionality that is not available in a default APIcast deployment. You can create your own policies, or use standard policies provided by Red Hat 3scale.
The following topics provide information about the standard APIcast policies, creating your own custom APIcast policies, and creating a policy chain.
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
Red Hat 3scale provides a method for adding custom policies, but does not support custom policies.
In order to modify APIcast behavior with custom policies, you must do the following:
- Add custom policies to APIcast
- Define a policy chain that configures APIcast policies
- Add the policy chain to APIcast
4.1. APIcast standard policies
3scale provides the following standard policies:
- Section 4.1.1, “3scale Auth Caching policy”
- Section 4.1.2, “3scale Batcher policy”
- Section 4.1.3, “Anonymous Access policy”
- Section 4.1.4, “CORS Request Handling policy”
- Section 4.1.5, “Echo policy”
- Section 4.1.6, “Edge Limiting policy”
- Section 4.1.7, “Header Modification policy”
- Section 4.1.8, “IP Check policy”
- Section 4.1.9, “JWT Claim Check policy”
- Section 4.1.10, “Liquid Context Debug policy”
- Section 4.1.11, “Logging policy”
- Section 4.1.12, “OAuth 2.0 Token Introspection policy”
- Section 4.1.13, “Prometheus metrics”
- Section 4.1.14, “Referrer policy”
- Section 4.1.15, “Retry policy”
- Section 4.1.16, “RH-SSO/Keycloak Role Check policy”
- Section 4.1.17, “Routing policy”
- Section 4.1.18, “SOAP policy”
- Section 4.1.19, “TLS Client Certificate Validation policy”
- Section 4.1.20, “Upstream policy”
- Section 4.1.21, “Upstream Connection policy”
- Section 4.1.22, “URL Rewriting policy”
- Section 4.1.23, “URL Rewriting with Captures policy”
You can enable and configure standard policies in the 3scale API Management.
4.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.
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
property | description | values | required? |
---|---|---|---|
caching_type |
The | 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.
4.1.2. 3scale Batcher policy
The 3scale Batcher policy provides an alternative to the standard APIcast authorization mechanism, in which one call to the 3scale backend (Service Management API) is made for each API request APIcast receives.
The 3scale Batcher policy reduces latency and increases throughput by significantly reducing the number of requests to the 3scale backend. In order to achieve this, this policy caches authorization statuses and batches usage reports.
When the 3scale Batcher policy is enabled, APIcast uses the following authorization flow:
On each request, the policy checks whether the credentials are cached:
- If the credentials are cached, the policy uses the cached authorization status instead of calling the 3scale backend.
- If the credentials are not cached, the policy calls the backend and caches the authorization status with a configurable Time to Live (TTL).
- Instead of reporting the usage corresponding to the request to the 3scale backend immediately, the policy accumulates their usage counters to report them to the backend in batches. A separate thread reports the accumulated usage counters to the 3scale backend in a single call, with a configurable frequency.
The 3scale Batcher policy improves the throughput, but with reduced accuracy. The usage limits and the current utilization are stored in 3scale, and APIcast can only get the correct authorization status when making calls to the 3scale backend. When the 3scale Batcher policy is enabled, there is a period of time APIcast is not sending calls to 3scale. During this window, applications making calls might go over the defined limits.
Use this policy for high-load APIs if the throughput is more important than the accuracy of the rate limiting. The 3scale Batcher policy gives better results in terms of accuracy when the reporting frequency and authorization TTL are much less than the rate limiting period. For example, if the limits are per day and the reporting frequency and authorization TTL are configured to be several minutes.
The 3scale Batcher policy supports the following configuration settings:
auths_ttl
: Sets the TTL in seconds when the authorization cache expires.When the authorization for the current call is cached, APIcast uses the cached value. After the time set in the
auths_ttl
parameter, APIcast removes the cache and calls the 3scale backend to retrieve the authorization status.-
batch_report_seconds
: Sets the frequency of batch reports APIcast sends to the 3scale backend. The default value is10
seconds.
To use this policy, enable both the 3scale APIcast
and 3scale Batcher
policy in the policy chain.
4.1.3. 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.
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 4.1. Anonymous Access Policy
4.1.4. 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
- Allowed credentials
- Allowed origin headers
The CORS request handling policy will block all unspecified CORS requests.
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
property | description | values | required? |
---|---|---|---|
allow_headers |
The | data type: array of strings, must be a CORS header | no |
allow_methods |
The | data type: array of enumerated strings [GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, CONNECT] | no |
allow_origin |
The | data type: string | no |
allow_credentials |
The | 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.
4.1.5. Echo policy
The Echo policy prints an incoming request back to the client, along with an optional HTTP status code.
Configuration properties
property | description | values | required? |
---|---|---|---|
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 | 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.
4.1.6. Edge Limiting policy
The Edge Limiting policy aims to provide flexible rate limiting for the traffic sent to the backend API and can be used with the default 3scale authorization. Some examples of the use cases supported by the policy include:
-
End-user rate limiting: Rate limit by the value of the "sub" (subject) claim of a JWT token passed in the Authorization header of the request (configured as
{{ jwt.sub }}
). - Requests Per Second (RPS) rate limiting.
- Global rate limits per service: Apply limits per service rather than per application.
- Concurrent connection limit: Set the number of concurrent connections allowed.
4.1.6.1. Types of limits
The policy supports the following types of limits that are provided by the lua-resty-limit-traffic library:
-
leaky_bucket_limiters
: Based on the "leaky_bucket" algorithm that is based on the average number of requests plus a maximum burst size. -
fixed_window_limiters
: Based on a fixed window of time (last X seconds). -
connection_limiters
: Based on the concurrent number of connections.
You can scope any limit by service or globally.
4.1.6.2. Limit definition
The limits have a key that encodes the entities that are used to define the limit (an IP, a service, an endpoint, an ID, the value for a specific header, etc.). The Key is specified in the key
parameter of the limiter.
key
is an object that is defined by the following properties:
-
name
: It is the name of the key. It must be unique in the scope. scope
: It defines the scope of the key. The supported scopes are:-
Per service scope that affects one service (
service
). -
Global scope that affects all the services (
global
).
-
Per service scope that affects one service (
name_type
: It defines how the "name" value will be evaluated:-
As plain text (
plain
) -
As Liquid (
liquid
)
-
As plain text (
Each limit also has some parameters that vary depending on their types:
leaky_bucket_limiters
:rate
,burst
.-
rate
: It defines how many requests can be made per second without a delay. -
burst
: It defines the amount of requests per second that can exceed the allowed rate. An artificial delay is introduced for requests above the allowed rate (specified byrate
). After exceeding the rate by more requests per second than defined inburst
, the requests get rejected.
-
-
fixed_window_limiters
:count
,window
.count
defines how many requests can be made per number of seconds defined inwindow
. connection_limiters
:conn
,burst
,delay
.-
conn
: Defines the maximum number of the concurrent connections allowed. It allows exceeding that number byburst
connections per second. -
delay
: It is the number of seconds to delay the connections that exceed the limit.
-
Examples
Allow 10 requests per minute to service_A:
{ "key": { "name": "service_A" }, "count": 10, "window": 60 }
Allow 100 connections with bursts of 10 with a delay of 1s:
{ "key": { "name": "service_A" }, "conn": 100, "burst": 10, "delay": 1 }
You can define several limits for each service. In case multiple limits are defined, the request can be rejected or delayed if at least one limit is reached.
4.1.6.3. Liquid templating
The Edge Limiting policy allows specifying the limits for the dynamic keys by supporting Liquid variables in the keys. For this, the name_type
parameter of the key must be set to "liquid" and the name
parameter can then use Liquid variables. Example: {{ remote_addr }}
for the client IP address or {{ jwt.sub }}
for the "sub" claim of the JWT token.
Example:
{ "key": { "name": "{{ jwt.sub }}", "name_type": "liquid" }, "count": 10, "window": 60 }
For more information about Liquid support, see Section 5.1, “Using variables and filters in policies”.
4.1.6.4. Applying conditions
The condition defines when the API gateway applies the limiter. You must specify at least one operation in the condition
property of each limiter.
condition
is defined by the following properties:
-
combine_op
. It is the boolean operator applied to the list of operations. The following two values are supported:or
andand
. operations
. It is a list of conditions that need to be evaluated. Each operation is represented by an object with the following properties:-
left
: The left part of the operation. -
left_type
: How theleft
property is evaluated (plain or liquid). -
right
: The right part of the operation. -
right_type
: How theright
property is evaluated (plain or liquid). -
op
: Operator applied between the left and the right parts. The following two values are supported:==
(equals) and!=
(not equals).
-
Example:
"condition": { "combine_op": "and", "operations": [ { "op": "==", "right": "GET", "left_type": "liquid", "left": "{{ http_method }}", "right_type": "plain" } ] }
4.1.6.5. Configuring the store
By default, Edge Limiting policy uses OpenResty shared dictionary for the rate limiting counters. However, an external Redis server can be used instead of the shared dictionary. This can be useful when multiple APIcast instances are used. Redis server can be configured using the redis_url
parameter.
4.1.6.6. Error handling
The limiters support the following parameters to configure how the errors are handled:
limits_exceeded_error
: Allows to configure the error status code and message that will be returned to the client when the configured limits are exceeded. The following parameters should be configured:-
status_code
: The status code of the request when the limits are exceeded. Default:429
. error_handling
: Specifies how to handle the error, with following options:-
exit
: Stops processing request and returns an error message. -
log
: Completes processing request and returns output logs.
-
-
configuration_error
: Allows to configure the error status code and message that will be returned to the client in case of incorrect configuration. The following parameters should be configured:-
status_code
: The status code when there is a configuration issue. Default:500
. error_handling
: Specifies how to handle the error, with following options:-
exit
: Stops processing request and returns an error message. -
log
: Completes processing request and returns output logs.
-
-
4.1.7. 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. Theadd
operation adds a value to an existing header. Theset
operation creates a header and value, and will overwrite an existing header’s value if one already exists. Thepush
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. Thedelete
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 beplain
for plain text orliquid
for evaluation as a Liquid template. For more information, see Section 5.1, “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.
4.1.8. IP Check policy
The IP Check policy is used to deny or allow requests based on a list of IPs.
Configuration properties
property | description | data type | required? |
---|---|---|---|
check_type |
The |
string, must be either | yes |
ips |
The | array of strings, must be valid IP addresses | yes |
error_msg |
The | string | no |
client_ip_sources |
The |
array of strings, valid options are one or more of | 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.
4.1.9. JWT Claim Check policy
4.1.9.1. About JWT Claim Check policy
Based on JSON Web Token (JWT) claims, the JWT Claim Check policy allows you to define new rules to block resource targets and methods.
In order to route based on the value of a JWT claim, you need a policy in the chain that validates the JWT and stores the claim in the context that the policies share.
If the JWT Claim Check policy is blocking a resource and a method, the policy also validates the JWT operations. Alternatively, in case that the method resource does not match, the request continues to the backend API.
Example: In case of a GET request, the JWT needs to have the role claim as admin, if not the request will be denied. On the other hand, any non GET request will not validate the JWT operations, so POST resource is allowed without JWT constraint.
{ "name": "apicast.policy.jwt_claim_check", "configuration": { "error_message": "Invalid JWT check", "rules": [ { "operations": [ {"op": "==", "jwt_claim": "role", "jwt_claim_type": "plain", "value": "admin"} ], "combine_op":"and", "methods": ["GET"], "resource": "/resource", "resource_type": "plain" } ] } }
4.1.9.2. Configuring JWT Claim Check policy in your policy chain
4.1.9.2.1. Prerequisites:
- You need to have access to a 3scale installation.
- You need to wait for all the deployments to finish.
4.1.9.2.2. Configuring the policy
- To add the JWT Claim Check policy to your API, follow the steps described in Enabling a standard Policy and choose JWT Claim Check.
- Click the JWT Claim Check link.
- To enable the policy, select the Enabled checkbox.
-
To add rules, click the plus
+
icon. - Specify the resource_type.
- Choose the operator.
- Indicate the resource controlled by the rule.
-
To add the allowed methods, click the plus
+
icon. - Type the error message to show to the user when traffic is blocked.
- When you have finished setting up your API with JWT Claim Check, click Update Policy.
Additionally:
-
You can add more resource types and allowed methods by clicking the plus
+
icon in the corresponding section.
To save your changes, click Update & test in Staging Environment.
4.1.10. Liquid Context Debug policy
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", ... } ... }
4.1.11. Logging policy
The Logging policy allows enabling or disabling APIcast (NGINX) access logs for each API service individually. By default, this policy is not enabled in policy chains.
This policy only supports the enable_access_logs
configuration parameter. To disable access logging for a service, enable the policy, unselect the enable_access_logs
parameter and click the Submit
button. To enable the access logs, select the enable_access_logs
parameter or disable the Logging policy.
You can combine the Logging policy with the global setting for the location of access logs. Set the APICAST_ACCESS_LOG_FILE
environment variable to configure the location of APIcast access logs. By default, this variable is set to /dev/stdout
, which is the standard output device. For further details about global APIcast parameters, see Chapter 6, APIcast environment variables.
4.1.12. OAuth 2.0 Token Introspection policy
The OAuth 2.0 Token Introspection policy allows validating the JSON Web Token (JWT) token used for services with the OpenID Connect (OIDC) authentication option using the Token Introspection Endpoint of the token issuer (Red Hat Single Sign-On).
APIcast supports the following authentication types in the auth_type
field to determine the Token Introspection Endpoint and the credentials APIcast uses when calling this endpoint:
-
use_3scale_oidc_issuer_endpoint
: APIcast uses the client credentials, Client ID and Client Secret, as well as the Token Introspection Endpoint from the OIDC Issuer setting configured on the Service Integration page. APIcast discovers the Token Introspection endpoint from thetoken_introspection_endpoint
field. This field is located in the.well-known/openid-configuration
endpoint that is returned by the OIDC issuer.
Example 4.1. Authentication type set to use_3scale_oidc_issuer_endpoint
"policy_chain": [ … { "name": "apicast.policy.token_introspection", "configuration": { "auth_type": "use_3scale_oidc_issuer_endpoint" } } … ],
client_id+client_secret
: This option enables you to specify a different Token Introspection Endpoint, as well as the Client ID and Client Secret APIcast uses to request token information. When using this option, set the following configuration parameters:-
client_id
: Sets the Client ID for the Token Introspection Endpoint. -
client_secret
: Sets the Client Secret for the Token Introspection Endpoint. -
introspection_url
: Sets the Introspection Endpoint URL.
-
Example 4.2. Authentication type set to client_id+client_secret
"policy_chain": [ … { "name": "apicast.policy.token_introspection", "configuration": { "auth_type": "client_id+client_secret", "client_id": "myclient", "client_secret": "mysecret", "introspection_url": "http://red_hat_single_sign-on/token/introspection" } } … ],
Regardless of the setting in the auth_type
field, APIcast uses Basic Authentication to authorize the Token Introspection call (Authorization: Basic <token>
header, where <token> is Base64-encoded <client_id>:<client_secret> setting).
The response of the Token Introspection Endpoint contains the active
attribute. APIcast checks the value of this attribute. Depending on the value of the attribute, APIcast authorizes or rejects the call:
-
true
: The call is authorized -
false
: The call is rejected with theAuthentication Failed
error
The policy allows enabling caching of the tokens to avoid calling the Token Introspection Endpoint on every call for the same JWT token. To enable token caching for the Token Introspection Policy, set the max_cached_tokens
field to a value from 0
, which disables the feature, and 10000
. Additionally, you can set a Time to Live (TTL) value from 1
to 3600
seconds for tokens in the max_ttl_tokens
field.
4.1.13. Prometheus metrics
Prometheus is a stand-alone, open source systems monitoring and alerting toolkit.
For this release of Red Hat 3scale, Prometheus installation and configuration are not supported. Optionally, you can use the community version of Prometheus to visualize metrics and alerts for APIcast-managed API services.
Prometheus metrics availability
APIcast integration with Prometheus is available for the following deployment options:
- Self-managed APIcast (both with hosted or on-premises API manager)
- Built-in APIcast on-premise
APIcast integration with Prometheus is not available in hosted API manager and hosted APIcast.
Prometheus metrics list
The following metrics are always available:
Metric | Description | Type | Labels |
---|---|---|---|
nginx_http_connections | Number of HTTP connections | gauge | state(accepted,active,handled,reading,total,waiting,writing) |
nginx_error_log | APIcast errors | counter | level(debug,info,notice,warn,error,crit,alert,emerg) |
openresty_shdict_capacity | Capacity of the dictionaries shared between workers | gauge | dict(one for every dictionary) |
openresty_shdict_free_space | Free space of the dictionaries shared between workers | gauge | dict(one for every dictionary) |
nginx_metric_errors_total | Number of errors of the Lua library that manages the metrics | counter | - |
total_response_time_seconds | Time needed to sent a response to the client (in seconds)
Note: To access the | histogram | service_id, service_system_name |
upstream_response_time_seconds | Response times from upstream servers (in seconds)
Note: To access the | histogram | service_id, service_system_name |
upstream_status | HTTP status from upstream servers
Note: To access the | counter | status, service_id, service_system_name |
threescale_backend_calls | Authorize and report requests to the 3scale backend (Apisonator) | counter | endpoint(authrep, auth, report), status(2xx, 4xx, 5xx) |
The following metrics are only available when using the 3scale Batcher policy:
Metric | Description | Type | Labels |
---|---|---|---|
batching_policy_auths_cache_hits | Hits in the auths cache of the 3scale batching policy | counter | - |
batching_policy_auths_cache_misses | Misses in the auths cache of the 3scale batching policy | counter | - |
Metrics with no value
If a metric has no value, the metric is hidden. For example, if nginx_error_log
has no errors to report, the nginx_error_log
metric is not displayed. It will only be visible once it has a value.
4.1.14. 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.
4.1.15. Retry policy
The Retry policy sets the number of retry requests to the upstream API. The retry policy is configured per service, so users can enable retries for as few or as many of their services as desired, as well as configure different retry values for different services.
As of 3scale 2.6, it is not possible to configure which cases to retry from the policy. This is controlled with the environment variable APICAST_UPSTREAM_RETRY_CASES
, which applies retry requests to all services. For more on this, check out APICAST_UPSTREAM_RETRY_CASES.
An example of the retry policy JSON
is shown below:
{ "$schema": "http://apicast.io/policy-v1/schema#manifest#", "name": "Retry", "summary": "Allows retry requests to the upstream", "description": "Allows retry requests to the upstream", "version": "builtin", "configuration": { "type": "object", "properties": { "retries": { "description": "Number of retries", "type": "integer", "minimum": 1, "maximum": 10 } } } }
4.1.16. 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 (RH-SSO). The realm roles are specified when you want to add role check to every client resource of 3scale.
There 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 instance 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 containing the Client ID.
methods: Use this parameter to list the allowed HTTP methods in APIcast, based on the user roles in RH-SSO. As examples, you can allow methods that have:
-
The
role1
realm role to access/resource1
. For those methods that do not have this realm role, you need to specify the blacklist. -
The
client1
role calledrole1
to access/resource1
. -
The
role1
androle2
realm roles to access/resource1
. Specify the roles in realm_roles. You can also indicate the scope for each role. -
The client role called
role1
of the application client, which is the recipient of the access token, to access/resource1
. Useliquid
client type to specify the JSON Web Token (JWT) information to the client. -
The client role including the client ID of the application client, the recipient of the access token, to access
/resource1
. Useliquid
client type to specify the JWT information to thename
of the client role. -
The client role called
role1
to access the resource including the application client ID. Useliquid
client type to specify the JWT information to theresource
.
-
The
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).
4.1.17. 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.
Routing is based on the following rules:
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.
4.1.17.1. Routing rules
- If multiple rules exist, the Routing policy applies the first match. You can sort these rules.
- If no rules match, the policy will not change the upstream and will use the defined Private Base URL defined in the service configuration.
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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": [] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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" } ] } } ] } }
4.1.17.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": "/" } ] } } ] } }
4.1.18. 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
property | description | values | required? |
---|---|---|---|
pattern |
The | data type: string | yes |
metric_system_name |
The | 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.
4.1.19. TLS Client Certificate Validation policy
4.1.19.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.
4.1.19.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.
4.1.19.2.1. Prerequisites:
- You need to have access to a 3scale installation.
- You need to wait for all the deployments to finish.
4.1.19.2.2. Setting up APIcast to work with the policy
To set up APIcast and configure it to terminate TLS, follow these steps:
You need to get the access token and deploy APIcast self-managed, as indicated in Deploying APIcast using the OpenShift template.
NoteAPIcast self-managed deployment is required as the APIcast instance needs to be reconfigured to use some certificates for the whole gateway.
For testing purposes only, you can use the lazy loader with no cache and staging environment and
--param
flags for the ease of testingoc new-app -f https://raw.githubusercontent.com/3scale/3scale-amp-openshift-templates/2.6.0.GA/apicast-gateway/apicast.yml --param CONFIGURATION_LOADER=lazy --param DEPLOYMENT_ENVIRONMENT=staging --param CONFIGURATION_CACHE=0
- Generate certificates for testing purposes. Alternatively, for production deployment, you can use the certificates provided by a Certificate Authority.
Create a Secret with TLS certificates
oc create secret tls apicast-tls --cert=ca/certs/server.crt --key=ca/keys/server.key
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
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
Expose 8443 on the Service
oc patch service apicast -p '{"spec":{"ports":[{"name":"https","port":8443,"protocol":"TCP"}]}}'
Delete the default route
oc delete route api-apicast-staging
Expose the
apicast
service as a routeoc create route passthrough --service=apicast --port=https --hostname=api-3scale-apicast-staging.$WILDCARD_DOMAIN
NoteThis step is needed for every API you are going to use and the domain changes for every API.
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
4.1.19.3. Configuring TLS Client Certificate Validation in your policy chain
4.1.19.3.1. Prerequisites
- You need 3scale login credentials.
- You need to have configured APIcast with the TLS Client Certificate Validation policy.
4.1.19.3.2. Configuring the policy
- 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.
- Click the TLS Client Certificate Validation link.
- To enable the policy, select the Enabled checkbox.
-
To add certificates to the whitelist, click the plus
+
icon. -
Specify the certificate including
-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
. - 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.
4.1.19.4. Verifying functionality of the TLS Client Certificate Validation policy
4.1.19.4.1. Prerequisites:
- You need 3scale login credentials.
- You need to have configured APIcast with the TLS Client Certificate Validation policy.
4.1.19.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
4.1.19.5. Removing a certificate from the whitelist
4.1.19.5.1. Prerequisites
- You need 3scale login credentials.
- You need to have set up APIcast with the TLS Client Certificate Validation policy.
- You need to have added the certificate to the whitelist, by configuring TLS Client Certificate Validation in your policy chain.
4.1.19.5.2. Removing a certificate
- Click the TLS Client Certificate Validation link.
-
To remove certificates from the whitelist, click the
x
icon. - When you have finished removing the certificates, click Update Policy.
To save your changes, click Update & test in Staging Environment.
4.1.19.6. Reference material
For more information about working with certificates, you can refer to Red Hat Certificate System.
4.1.20. 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:
property | description | values | required? |
---|---|---|---|
regex |
The | data type: string, Must be a valid regular expression syntax | yes |
url |
Using the | 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.
4.1.21. Upstream Connection policy
4.1.21.1. About Upstream Connection policy
The Upstream Connection policy allows you to change the default values of the following directives, for each API, depending on how you have configured the API back end server in your 3scale installation:
-
proxy_connect_timeout
-
proxy_send_timeout
-
proxy_read_timeout
4.1.21.2. Configuring Upstream Connection in your policy chain
4.1.21.2.1. Prerequisites:
- You need to have access to a 3scale installation.
- You need to wait for all the deployments to finish.
4.1.21.2.2. Configuring the policy
- To add the Upstream Connection policy to your API, follow the steps described in Enabling a standard Policy and choose Upstream connection.
- Click the Upstream connection link.
- To enable the policy, select the Enabled checkbox.
Configure the options for the connections to the upstream:
- send_timeout
- connect_timeout
- read_timeout
- When you have finished setting up your API with Upstream connection, click Update Policy.
To save your changes, click Update & test in Staging Environment.
4.1.22. 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.
4.1.22.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
andgsub
. Thesub
operation replaces only the first occurrence of a match with your specified regular expression. Thegsub
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).
4.1.22.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 thedelete
operation the value is not taken into account. -
value_type
(optional): Defines how the query argument value is evaluated and can either beplain
for plain text orliquid
for evaluation as a Liquid template. For more information, see Section 5.1, “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:
-
The substring
/api/v1/
matches the only path rewriting command and it is replaced by/internal/
. -
user_key
query argument is deleted. -
The value
pushvalue
is added as an additional value to thepusharg
query argument. -
The value
original
of the query argumentsetarg
is replaced with the configured valuesetvalue
. -
The command
add
was not applied because the query argumentaddarg
is not present in the original URL.
For information on how to configure policies, see the Creating a policy chain section of the documentation.
4.1.23. URL Rewriting with Captures policy
The URL Rewriting with Captures policy is an alternative to the Section 4.1.22, “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 retrieves 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 tomatch_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 thematch_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 thematch_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
4.2. Enabling a policy in the Admin Portal
Perform the following steps to enable policies in the Admin Portal:
- Log in to 3scale.
- Navigate to the API service.
-
From [your_API_name] > Integration > Configuration, select
edit APIcast configuration
. -
Under the POLICIES section, click
add policy
. - Select the policy you want to add and fill out the required fields.
- Click the Update and test in Staging Environment button to save the policy chain.
4.3. Creating custom APIcast policies
You can create custom APIcast policies entirely or modify the standard policies.
In order to create custom policies, you must understand the following:
- Policies are written in Lua.
- Policies must adhere to and be placed in the proper file directory.
- Policy behavior is affected by how they are placed in a policy chain.
- The interface to add custom policies is fully supported, but not the custom policies themselves.
4.4. Adding custom policies to APIcast
If you have created custom policies, you must add them to APIcast. How you do this depends on where APIcast is deployed.
You can add custom policies to the following APIcast self-managed deployments:
- APIcast built-in gateways as part of a 3scale on-premises deployment on OpenShift
- APIcast on OpenShift and the Docker containerized environment
You cannot add custom policies to APIcast hosted.
Never make policy changes directly onto a production gateway. Always test your changes.
4.4.1. Adding custom policies to the built-in APIcast
To add custom APIcast policies to an on-premises deployment, you must build an OpenShift image containing your custom policies and add it to your deployment. Red Hat 3scale provides a sample repository you can use as a framework to create and add custom policies to an on-premises deployment.
This sample repository contains the correct directory structure for a custom policy, as well as a template which creates an image stream and BuildConfigs for building a new APIcast OpenShift image containing any custom policies you create.
When you build apicast-custom-policies
, the build process "pushes" a new image to the amp-apicast:latest
tag. When there is an image change on this image stream tag (:latest
), both the apicast-staging and the apicast-production tags, by default, are configured to automatically start new deployment. To avoid any disruptions to your production service (or staging, if you prefer) it is recommended to disable automatic deployment ("Automatically start a new deployment when the image changes" checkbox), or configure a different image stream tag for production (e.g. amp-apicast:production
).
Follow these steps to add a custom policy to an on-premises deployment:
- Fork the https://github.com/3scale/apicast-example-policy [public repository with the policy example] or create a private repository with its content. You need to have the code of your custom policy available in a Git repository for OpenShift to build the image. Note that in order to use a private Git repository, you must set up the secrets in OpenShift.
- Clone the repository locally, add the implementation for your policy, and push the changes to your Git repository.
Update the
openshift.yml
template. Specifically, change the following parameters:-
spec.source.git.uri: https://github.com/3scale/apicast-example-policy.git
in the policy BuildConfig – change it to your Git repository location. -
spec.source.images[0].paths.sourcePath: /opt/app-root/policies/example
in the custom policies BuildConfig - changeexample
to the name of the custom policy that you have added under thepolicies
directory in the repository. -
Optionally, update the OpenShift object names and image tags. However, you must ensure that the changes are coherent (example:
apicast-example-policy
BuildConfig builds and pushes theapicast-policy:example
image that is then used as a source by theapicast-custom-policies
BuildConfig. So, the tag should be the same).
-
Create the OpenShift objects by running the command:
oc new-app -f openshift.yml --param AMP_RELEASE=2.6.0
In case the builds do not start automatically, run the following two commands. In case you changed it, replace
apicast-example-policy
with your own BuildConfig name (e.g.apicast-<name>-policy
). Wait for the first command to complete before you execute the second one.oc start-build apicast-example-policy oc start-build apicast-custom-policies
If the build-in APIcast images have a trigger on them tracking the changes in the amp-apicast:latest
image stream, the new deployment for APIcast will start. After apicast-staging
has restarted, go to the Integration page on the admin portal, and click the Add Policy button to see your custom policy listed. After selecting and configuring it, click Update & test in Staging Environment to make your custom policy work in the staging APIcast.
4.4.2. Adding custom policies to APIcast on another OpenShift Container Platform
You can add custom policies to APIcast on OpenShift Container Platform (OCP) by fetching APIcast images containing your custom policies from the Integrated OpenShift Container Platform registry.
Add custom policies to APIcast on another OpenShift Container Platform
- Add policies to APIcast built-in
- If you are not deploying your APIcast gateway on your primary OpenShift cluster, establish access to the internal registry on your primary OpenShift cluster.
- Download the 3scale 2.6 APIcast OpenShift template.
To modify the template, replace the default
image
directory with the full image name in your internal registry.image: <registry>/<project>/amp-apicast:latest
Deploying APIcast using the OpenShift template, specifying your customized image:
oc new-app -f customizedApicast.yml
When custom policies are added to APIcast and a new image is built, those policies are automatically displayed as available in the Admin Portal when APIcast is deployed with the image. Existing services can see this new policy in the list of available policies, so it can be used in any policy chain.
When a custom policy is removed from an image and APIcast is restarted, the policy will no longer be available in the list, so you can no longer add it to a policy chain.
4.5. Creating a policy chain in 3scale
Create a policy chain in 3scale as part of your APIcast gateway configuration. Follow these steps to modify the policy chain in the UI:
- Log in to your AMP
Navigate to the API service
From [your_API_name] > Integration > Configuration, select
edit APIcast configuration
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.
- Click the Update and test in Staging Environment button to save the policy chain
4.6. Creating a policy chain JSON configuration file
If you are using a native deployment of APIcast, you can create a JSON configuration file to control your policy chain outside of the AMP.
A JSON configuration file policy chain contains a JSON array composed of the following information:
-
the
services
object with anid
value that specifies which service the policy chain applies to by number -
the
proxy
object, which contains the policy_chain and subsequent objects -
the
policy_chain
object, which contains the values that define the policy chain -
individual
policy
objects which specify bothname
andconfiguration
data necessary to identify the policy and configure policy behavior
The following is an example policy chain for a custom policy sample_policy_1
and the API introspection standard policy token_introspection
:
{ "services":[ { "id":1, "proxy":{ "policy_chain":[ { "name":"sample_policy_1", "version": "1.0", "configuration":{ "sample_config_param_1":["value_1"], "sample_config_param_2":["value_2"] } }, { "name": "token_introspection", "version": "builtin", "configuration": { introspection_url:["https://tokenauthorityexample.com"], client_id:["exampleName"], client_secret:["secretexamplekey123"] }, { "name": "apicast", "version": "builtin", } ] } } ] }
All policy chains must include the built-in policy apicast
. Where you place APIcast in the policy chain will affect policy behavior.