/images/resources/tutorials/integration/plugin-kubernetes.png

Use Kubernetes API Gateway Plugins

On this page

The Expose OAuth Endpoints from Kubernetes tutorial explains how to use an API gateway to enable ingress into a cluster. A gateway is a hosting best practice rather than exposing APIs or the authorization server directly to the internet. Many organizations handle cross-cutting concerns in the gateway and then route requests to load balanced Kubernetes services. Using a central point of ingress also saves costs as it reduces the number of load balancers.

API Gateway Extensibility

Different API gateways provide varying levels of extensibility and customization. Some may require plugins to use low level languages like C, whereas some NGINX derived gateways, like Kong Open Source, provide support for writing plugins in higher level languages like LUA. Kong has a wide range of plugins to support customization use cases.

This tutorial summarizes the Kubernetes specific aspects of integrating the Phantom Token and OAuth Proxy plugins. It explains the Kubernetes specific setups using Kong and NGINX ingress as two representatives for cloud-native API gateways. The following tutorials provide further information, such as how to produce a custom Docker image containing each plugin and its dependencies.

Phantom Token Integration

Kong provides a custom resource definition called KongPlugin to enable the plugin configuration to be expressed once. For the phantom token plugin, apply YAML settings in the following format for all namespaces that run the plugin in front of API routes:

yaml
12345678910
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
name: phantom-token
plugin: phantom-token
config:
introspection_endpoint: http://curity-idsvr-runtime-svc.curity:8443/oauth/v2/oauth-introspect
client_id: api-gateway-client
client_secret: Password1
token_cache_seconds: 900

Then, create an API gateway route that applies the KongPlugin resource using an annotation. Create Ingress or HttpRoute resources for the namespace of the upstream Kubernetes service:

yaml
1234567891011121314151617181920
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: demoapi-route
annotations:
konghq.com/plugins: phantom-token
spec:
parentRefs:
- name: kong-gateway
namespace: kong
hostnames:
- api.demoapp.example
rules:
- matches:
- path:
value: /
backendRefs:
- name: demoapi-svc
kind: Service
port: 8000

For the NGINX API gateway, configure settings differently for the NGINX gateway fabric or the NGINX ingress controller.

To configure the NGINX gateway fabric, use the SnippetsFilter API. Extract plugin settings that require contexts like main, http and http.server into a base snippet. Then put http.server.location context settings into its own snippet.

yaml
12345678910111213141516171819202122232425262728293031
apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
name: phantom-token-base
spec:
snippets:
- context: main
value: load_module /usr/lib/nginx/modules/ngx_curity_http_phantom_token_module.so;
- context: http
value: proxy_cache_path cache levels=1:2 keys_zone=api_cache:10m max_size=10g inactive=60m use_temp_path=off;
- context: http.server
value: |
location curity {
proxy_pass http://curity-idsvr-runtime-svc.curity.svc.cluster.local:8443/oauth/v2/oauth-introspect;
proxy_cache_methods POST;
proxy_cache api_cache;
proxy_cache_key §request_body;
proxy_ignore_headers Set-Cookie;
}
---
apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
name: phantom-token
spec:
snippets:
- context: http.server.location
value: |
phantom_token on;
phantom_token_client_credential api-gateway-client Password123;
phantom_token_introspection_endpoint curity;

Then reference snippets in the HTTPRoute configuration.

yaml
1234567891011121314151617181920212223242526272829
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: demoapi-route
spec:
parentRefs:
- name: nginx-gateway
namespace: nginx
hostnames:
- api.demoapp.example
rules:
- matches:
- path:
value: /
filters:
- type: ExtensionRef
extensionRef:
group: gateway.nginx.org
kind: SnippetsFilter
name: phantom-token-base
- type: ExtensionRef
extensionRef:
group: gateway.nginx.org
kind: SnippetsFilter
name: phantom-token
backendRefs:
- name: demoapi-svc
kind: Service
port: 8000

The following example tutorials show how to integrate the phantom token plugin with NGINX in the main cloud Kubernetes systems. The GKE deployment can also integrate with the Kong gateway:

OAuth Proxy Integration

To pre-process cookies during API requests for the Kong API gateway, follow a similar approach to configure both CORS and the OAuth Proxy plugin:

yaml
12345678910111213141516171819
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
name: cors
plugin: cors
config:
origins:
- https://www.demoapp.example
credentials: true
max_age: 86400
---
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
name: oauth-proxy
plugin: oauth-proxy
config:
cookie_key: "$TH_COOKIE_KEY"
cookie_key_pass: "$TH_COOKIE_KEY_PASS"

Then, create an API gateway route that applies the KongPlugin resources using an annotation. Create Ingress or HttpRoute resources for the namespace of the upstream Kubernetes service:

yaml
1234567891011121314151617181920
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: demoapi-route
annotations:
konghq.com/plugins: cors,oauth-proxy
spec:
parentRefs:
- name: kong-gateway
namespace: kong
hostnames:
- api.demoapp.example
rules:
- matches:
- path:
value: /
backendRefs:
- name: demoapi-svc
kind: Service
port: 8000

For the NGINX API gateway, configure settings differently for the NGINX gateway fabric or the NGINX ingress controller.

To configure the NGINX gateway fabric, express the settings in SnippetsFilter resources. Extract the main context that loads the module into a base snippet. Then put http.server.location context settings into its own snippet.

yaml
1234567891011121314151617181920212223242526272829303132333435363738394041424344
apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
name: oauth-proxy-base
spec:
snippets:
- context: main
value: load_module /usr/lib/nginx/modules/ngx_curity_http_phantom_token_module.so;
---
apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
name: oauth-proxy
spec:
snippets:
- context: http.server.location
value: |
set $cors_mode '';
if ($http_origin = 'http://www.demoapp.example') {
set $cors_mode 'matched';
}
if ($request_method = 'OPTIONS') {
set $cors_mode '${cors_mode}-preflight';
}
if ($cors_mode = 'matched') {
add_header 'access-control-allow-origin' $http_origin always;
add_header 'access-control-allow-credentials' true always;
add_header 'vary' 'origin';
}
if ($cors_mode = 'matched-preflight') {
add_header 'access-control-allow-origin' $http_origin;
add_header 'access-control-allow-credentials' true;
add_header 'access-control-allow-methods' 'GET,POST,PUT,PATCH,DELETE';
add_header 'access-control-allow-headers' $http_access_control_request_headers;
add_header 'access-control-max-age' 86400;
add_header 'vary' 'origin, access-control-request-headers';
return 200;
}
oauth_proxy on;
oauth_proxy_key "${TH_COOKIE_KEY}" "${TH_COOKIE_KEY_PASS}";

Then reference snippets in the HTTPRoute configuration.

yaml
1234567891011121314151617181920212223242526272829
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: demoapi-route
spec:
parentRefs:
- name: nginx-gateway
namespace: nginx
hostnames:
- api.demoapp.example
rules:
- matches:
- path:
value: /
filters:
- type: ExtensionRef
extensionRef:
group: gateway.nginx.org
kind: SnippetsFilter
name: oauth-proxy-base
- type: ExtensionRef
extensionRef:
group: gateway.nginx.org
kind: SnippetsFilter
name: oauth-proxy
backendRefs:
- name: demoapi-svc
kind: Service
port: 8000

Deployment Example

The GitHub link at the top of this page provides some Kubernetes deployment examples that run on a local computer. The Curity Token Handler example provides a completed backend deployment and also an example Single Page Application, so that you can run an end-to-end flow.

Conclusion

The leading cloud native API gateways enable advanced API behaviors with plugins or modules. Using annotations and custom resources, API gateways can pre-process requests to convert opaque access tokens or HTTP cookies into JWT access tokens for upstream APIs. These patterns enable clients to follow security best practices and APIs to only work with JWT access tokens.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial