OpenID Connect with Curity
Integrate Kong Gateway and the Curity Identity Server for introspection using the Phantom Token pattern.
The OpenID Connect plugin introspects an incoming opaque access token and receives a JWT in the introspection response from the Curity Identity Server. As part of the introspection, the OpenID Connect plugin validates that required scopes are available in the introspected token.
- If the correct scopes are missing, access to the requested upstream service is denied.
- If access is granted, the JWT from the introspection response is added to a header and forwarded to the upstream service where it can be consumed.
Prerequisites
-
An introspection endpoint configured with the Phantom Token Approach.
Environment variables
-
ISSUER
: The issuer authentication URL for your IdP. For Curity, that typically looks like this:https://idsvr.example.com/oauth/v2/oauth-anonymous
. -
CLIENT_ID
: The client ID that the plugin uses when it calls authenticated endpoints of the IdP. -
CLIENT_SECRET
: The client secret needed to connect to Curity.
Add this section to your declarative configuration file:
_format_version: "3.0"
plugins:
- name: openid-connect
config:
issuer: ${{ env "DECK_ISSUER" }}
client_id:
- ${{ env "DECK_CLIENT_ID" }}
client_secret:
- ${{ env "DECK_CLIENT_SECRET" }}
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
Make the following request:
curl -i -X POST http://localhost:8001/plugins/ \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make the following request:
curl -X POST https://{region}.api.konghq.com/v2/control-planes/{controlPlaneId}/core-entities/plugins/ \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make sure to replace the following placeholders with your own values:
-
region
: Geographic region where your Kong Konnect is hosted and operates. -
controlPlaneId
: Theid
of the control plane. -
KONNECT_TOKEN
: Your Personal Access Token (PAT) associated with your Konnect account.
See the Konnect API reference to learn about region-specific URLs and personal access tokens.
echo "
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: openid-connect
namespace: kong
annotations:
kubernetes.io/ingress.class: kong
labels:
global: 'true'
config:
issuer: '$ISSUER'
client_id:
- '$CLIENT_ID'
client_secret:
- '$CLIENT_SECRET'
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
plugin: openid-connect
" | kubectl apply -f -
Prerequisite: Configure your Personal Access Token
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
provider "konnect" {
personal_access_token = "$KONNECT_TOKEN"
server_url = "https://us.api.konghq.com/"
}
Add the following to your Terraform configuration to create a Konnect Gateway Plugin:
resource "konnect_gateway_plugin_openid_connect" "my_openid_connect" {
enabled = true
config = {
issuer = var.issuer
client_id = [var.client_id]
client_secret = [var.client_secret]
scopes_required = ["openid"]
hide_credentials = true
upstream_access_token_header = "nil"
upstream_headers_claims = ["phantom_token"]
upstream_headers_names = ["phantom_token"]
auth_methods = ["introspection"]
}
control_plane_id = konnect_gateway_control_plane.my_konnect_cp.id
}
This example requires the following variables to be added to your manifest. You can specify values at runtime by setting TF_VAR_name=value
.
variable "client_secret" {
type = string
}
Add this section to your declarative configuration file:
_format_version: "3.0"
plugins:
- name: openid-connect
service: serviceName|Id
config:
issuer: ${{ env "DECK_ISSUER" }}
client_id:
- ${{ env "DECK_CLIENT_ID" }}
client_secret:
- ${{ env "DECK_CLIENT_SECRET" }}
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
Make sure to replace the following placeholders with your own values:
-
serviceName|Id
: Theid
orname
of the service the plugin configuration will target.
Make the following request:
curl -i -X POST http://localhost:8001/services/{serviceName|Id}/plugins/ \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make sure to replace the following placeholders with your own values:
-
serviceName|Id
: Theid
orname
of the service the plugin configuration will target.
Make the following request:
curl -X POST https://{region}.api.konghq.com/v2/control-planes/{controlPlaneId}/core-entities/services/{serviceId}/plugins/ \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make sure to replace the following placeholders with your own values:
-
region
: Geographic region where your Kong Konnect is hosted and operates. -
controlPlaneId
: Theid
of the control plane. -
KONNECT_TOKEN
: Your Personal Access Token (PAT) associated with your Konnect account. -
serviceId
: Theid
of the service the plugin configuration will target.
See the Konnect API reference to learn about region-specific URLs and personal access tokens.
echo "
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: openid-connect
namespace: kong
annotations:
kubernetes.io/ingress.class: kong
config:
issuer: '$ISSUER'
client_id:
- '$CLIENT_ID'
client_secret:
- '$CLIENT_SECRET'
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
plugin: openid-connect
" | kubectl apply -f -
Next, apply the KongPlugin
resource by annotating the service
resource:
kubectl annotate -n kong service SERVICE_NAME konghq.com/plugins=openid-connect
Prerequisite: Configure your Personal Access Token
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
provider "konnect" {
personal_access_token = "$KONNECT_TOKEN"
server_url = "https://us.api.konghq.com/"
}
Add the following to your Terraform configuration to create a Konnect Gateway Plugin:
resource "konnect_gateway_plugin_openid_connect" "my_openid_connect" {
enabled = true
config = {
issuer = var.issuer
client_id = [var.client_id]
client_secret = [var.client_secret]
scopes_required = ["openid"]
hide_credentials = true
upstream_access_token_header = "nil"
upstream_headers_claims = ["phantom_token"]
upstream_headers_names = ["phantom_token"]
auth_methods = ["introspection"]
}
control_plane_id = konnect_gateway_control_plane.my_konnect_cp.id
service = {
id = konnect_gateway_service.my_service.id
}
}
This example requires the following variables to be added to your manifest. You can specify values at runtime by setting TF_VAR_name=value
.
variable "client_secret" {
type = string
}
Add this section to your declarative configuration file:
_format_version: "3.0"
plugins:
- name: openid-connect
route: routeName|Id
config:
issuer: ${{ env "DECK_ISSUER" }}
client_id:
- ${{ env "DECK_CLIENT_ID" }}
client_secret:
- ${{ env "DECK_CLIENT_SECRET" }}
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
Make sure to replace the following placeholders with your own values:
-
routeName|Id
: Theid
orname
of the route the plugin configuration will target.
Make the following request:
curl -i -X POST http://localhost:8001/routes/{routeName|Id}/plugins/ \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make sure to replace the following placeholders with your own values:
-
routeName|Id
: Theid
orname
of the route the plugin configuration will target.
Make the following request:
curl -X POST https://{region}.api.konghq.com/v2/control-planes/{controlPlaneId}/core-entities/routes/{routeId}/plugins/ \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"name": "openid-connect",
"config": {
"issuer": "'$ISSUER'",
"client_id": [
"'$CLIENT_ID'"
],
"client_secret": [
"'$CLIENT_SECRET'"
],
"scopes_required": [
"openid"
],
"hide_credentials": true,
"upstream_access_token_header": "nil",
"upstream_headers_claims": [
"phantom_token"
],
"upstream_headers_names": [
"phantom_token"
],
"auth_methods": [
"introspection"
]
}
}
'
Make sure to replace the following placeholders with your own values:
-
region
: Geographic region where your Kong Konnect is hosted and operates. -
controlPlaneId
: Theid
of the control plane. -
KONNECT_TOKEN
: Your Personal Access Token (PAT) associated with your Konnect account. -
routeId
: Theid
of the route the plugin configuration will target.
See the Konnect API reference to learn about region-specific URLs and personal access tokens.
echo "
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: openid-connect
namespace: kong
annotations:
kubernetes.io/ingress.class: kong
config:
issuer: '$ISSUER'
client_id:
- '$CLIENT_ID'
client_secret:
- '$CLIENT_SECRET'
scopes_required:
- openid
hide_credentials: true
upstream_access_token_header: nil
upstream_headers_claims:
- phantom_token
upstream_headers_names:
- phantom_token
auth_methods:
- introspection
plugin: openid-connect
" | kubectl apply -f -
Next, apply the KongPlugin
resource by annotating the httproute
or ingress
resource:
kubectl annotate -n kong httproute konghq.com/plugins=openid-connect
kubectl annotate -n kong ingress konghq.com/plugins=openid-connect
Prerequisite: Configure your Personal Access Token
terraform {
required_providers {
konnect = {
source = "kong/konnect"
}
}
}
provider "konnect" {
personal_access_token = "$KONNECT_TOKEN"
server_url = "https://us.api.konghq.com/"
}
Add the following to your Terraform configuration to create a Konnect Gateway Plugin:
resource "konnect_gateway_plugin_openid_connect" "my_openid_connect" {
enabled = true
config = {
issuer = var.issuer
client_id = [var.client_id]
client_secret = [var.client_secret]
scopes_required = ["openid"]
hide_credentials = true
upstream_access_token_header = "nil"
upstream_headers_claims = ["phantom_token"]
upstream_headers_names = ["phantom_token"]
auth_methods = ["introspection"]
}
control_plane_id = konnect_gateway_control_plane.my_konnect_cp.id
route = {
id = konnect_gateway_route.my_route.id
}
}
This example requires the following variables to be added to your manifest. You can specify values at runtime by setting TF_VAR_name=value
.
variable "client_secret" {
type = string
}