# Common Controls

The following are sample Gateway controls for common scenarios.

# Returning an HTTP Redirect

plugins:
- name: pre-function
    tags: [ _NS_ ]
    config:
      access:
      - "kong.response.exit(307, 'site moved - redirecting...', {['Location'] = 'https://my-new-url.site'})"

# Request Termination

plugins:
- name: request-termination
  tags: [ _NS_ ]
  config:
    status_code: 400
    message: API not implemented yet!

# Adding Headers For Best Security Practices

plugins:
- name: response-transformer
  tags: [ _NS_ ]
  config:
    add:
      headers:
      - "X-Frame-Options: DENY"
      - "X-XSS-Protection: 1; mode=block"
      - "X-Content-Type-Options: nosniff"
      - "Strict-Transport-Security: max-age=31536000"
      - "Content-Security-Policy: script-src 'self'"

For further information on individual headers, see: https://owasp.org/www-project-secure-headers/

# Rate Limit

# Option 1 - Using a Distributed Cache

This provides the most accurate because it uses a centralized Cache that all Kong nodes use. The downside is that there is a 100-200ms latency.

plugins:
- name: rate-limiting
  tags: [ _NS_ ]
  config:
    fault_tolerant: true
    hide_client_headers: false
    limit_by: ip
    minute: 30000
    second: null
    hour: null
    day: null
    month: null
    year: null

# Option 2 - Node Local Caching

This provides the fastest rate limiting option, with minimal latency (~1ms). The downside is that it is local to each node so calculating the actual load on your upstream is a function of the number of nodes.

plugins:
- name: rate-limiting
  tags: [ _NS_ ]
  config:
    policy: local
    fault_tolerant: true
    hide_client_headers: false
    limit_by: ip
    minute: 30000
    second: null
    hour: null
    day: null
    month: null
    year: null

# Two-tiered access setup

The key-auth and jwt-keycloak plugins support the concept of allowing "anonymous" access, which allows you to define a "free" service which might have limits around it (like only allowing 100 requests/minute), and then an "elevated" access where the Consumer would get an improved level of service, such as higher rate limits.

There is a global "anonymous" consumer that is identified as "ce26955a-cf08-4907-9427-12d01c8bd94c" in both our Test and Production environments.

To enable anonymous access to your API, update your plugin configuration with:

# key-auth

- name: key-auth
  tags: [ _NS_ ]
  config:
    ...
    anonymous: ce26955a-cf08-4907-9427-12d01c8bd94c

# jwt-keycloak

- name: jwt-keycloak
  tags: [ _NS_ ]
  config:
    ...
    consumer_match: true
    consumer_match_ignore_not_found: false
    consumer_match_claim_custom_id: false
    anonymous: ce26955a-cf08-4907-9427-12d01c8bd94c

# Event Metric

This pre-function allows you to collect arbitrary metrics that you can then track in the APS Grafana instance (https://grafana.apps.gov.bc.ca/).

echo '
if kong.request.get_query_arg("layers") ~= "WILDFIRE" then
    kong.service.request.set_header("x-event", "to-beid")
else
    kong.service.request.set_header("x-event", "to-ocp")
end
' | \
python3 -c "import json,sys; script=sys.stdin.read(); print(json.dumps(script.strip()))"

- name: pre-function
  tags: [ _NS_ ]
  config:
    access:
    - "<PUT OUTPUT FROM ABOVE HERE>"

# Disabling global error handling

APS has a global post-function plugin that transforms the response message if the following HTTP status codes are returned by the upstream service:

s408 = "Request timeout",
s411 = "Length required",
s412 = "Precondition failed",
s413 = "Payload too large",
s414 = "URI too long",
s417 = "Expectation failed",
s494 = "Request header or cookie too large",
s500 = "An unexpected error occurred",
s502 = "An invalid response was received from the upstream server",
s503 = "The upstream server is currently unavailable",
s504 = "The upstream server is timing out",

If this transformation is not desired, you can override it by including the following plugin on your Service:

plugins:
  - name: post-function
    tags: [ _NS_ ]
    config:
      rewrite:
      - "--"