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.
- Kong Phantom Token Plugin
- NGINX Phantom Token Module
- Kong OAuth Proxy Plugin
- NGINX OAuth Proxy Module
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:
kind: KongPluginapiVersion: configuration.konghq.com/v1metadata:name: phantom-tokenplugin: phantom-tokenconfig:introspection_endpoint: http://curity-idsvr-runtime-svc.curity:8443/oauth/v2/oauth-introspectclient_id: api-gateway-clientclient_secret: Password1token_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:
kind: HTTPRouteapiVersion: gateway.networking.k8s.io/v1metadata:name: demoapi-routeannotations:konghq.com/plugins: phantom-tokenspec:parentRefs:- name: kong-gatewaynamespace: konghostnames:- api.demoapp.examplerules:- matches:- path:value: /backendRefs:- name: demoapi-svckind: Serviceport: 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.
apiVersion: gateway.nginx.org/v1alpha1kind: SnippetsFiltermetadata:name: phantom-token-basespec:snippets:- context: mainvalue: load_module /usr/lib/nginx/modules/ngx_curity_http_phantom_token_module.so;- context: httpvalue: proxy_cache_path cache levels=1:2 keys_zone=api_cache:10m max_size=10g inactive=60m use_temp_path=off;- context: http.servervalue: |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/v1alpha1kind: SnippetsFiltermetadata:name: phantom-tokenspec:snippets:- context: http.server.locationvalue: |phantom_token on;phantom_token_client_credential api-gateway-client Password123;phantom_token_introspection_endpoint curity;
Then reference snippets in the HTTPRoute
configuration.
kind: HTTPRouteapiVersion: gateway.networking.k8s.io/v1metadata:name: demoapi-routespec:parentRefs:- name: nginx-gatewaynamespace: nginxhostnames:- api.demoapp.examplerules:- matches:- path:value: /filters:- type: ExtensionRefextensionRef:group: gateway.nginx.orgkind: SnippetsFiltername: phantom-token-base- type: ExtensionRefextensionRef:group: gateway.nginx.orgkind: SnippetsFiltername: phantom-tokenbackendRefs:- name: demoapi-svckind: Serviceport: 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:
kind: KongPluginapiVersion: configuration.konghq.com/v1metadata:name: corsplugin: corsconfig:origins:- https://www.demoapp.examplecredentials: truemax_age: 86400---kind: KongPluginapiVersion: configuration.konghq.com/v1metadata:name: oauth-proxyplugin: oauth-proxyconfig: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:
kind: HTTPRouteapiVersion: gateway.networking.k8s.io/v1metadata:name: demoapi-routeannotations:konghq.com/plugins: cors,oauth-proxyspec:parentRefs:- name: kong-gatewaynamespace: konghostnames:- api.demoapp.examplerules:- matches:- path:value: /backendRefs:- name: demoapi-svckind: Serviceport: 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.
apiVersion: gateway.nginx.org/v1alpha1kind: SnippetsFiltermetadata:name: oauth-proxy-basespec:snippets:- context: mainvalue: load_module /usr/lib/nginx/modules/ngx_curity_http_phantom_token_module.so;---apiVersion: gateway.nginx.org/v1alpha1kind: SnippetsFiltermetadata:name: oauth-proxyspec:snippets:- context: http.server.locationvalue: |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.
kind: HTTPRouteapiVersion: gateway.networking.k8s.io/v1metadata:name: demoapi-routespec:parentRefs:- name: nginx-gatewaynamespace: nginxhostnames:- api.demoapp.examplerules:- matches:- path:value: /filters:- type: ExtensionRefextensionRef:group: gateway.nginx.orgkind: SnippetsFiltername: oauth-proxy-base- type: ExtensionRefextensionRef:group: gateway.nginx.orgkind: SnippetsFiltername: oauth-proxybackendRefs:- name: demoapi-svckind: Serviceport: 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