This repository is an implementation of an HTTP DCR bridge to enable integration between the Konnect Dev Portal and Ory Hydra. The HTTP DCR bridge acts as a proxy and translation layer between Hydra Admin API and DCR applications made in the Konnect Dev Portal.
Comment: the Hydra DCR requires to re-use the registration_access_token
(got on the application creation) for the refresh and the deletion of the application. As there is no way to store the registration_access_token
in Konnect, we use the Hydra Admin API (port 4445) (and not the Hydra DCR mechanism) to manage the full lifecycle of the Application. The Hydra Admin API has to be secured by the Kong Gateway and, at least, an Authentication mechanism (Bearer token or Basic) configured with the OpenId Connect plugin.
This repository is forked from https://github.com/Kong/konnect-portal-dcr-handler. Please read the README.md of this repo.
The HTTP DCR bridge can be built and deployed in 2 ways:
- As a Serverless solution on AWS Lambda
- As a Docker image deployed on Docker / Kubernetes / OpenShift
The HTTP DCR bridge is based on a lightweight fastify Node.js server
Fork this repository
Do a git clone of your forked repository
git clone https://github.com/<**YOUR_NAME**>/konnect-ory-hydra-portal-dcr.git
Install Yarn ^1.22.x
If you want to build a Docker image (for the HTTP DCR bridge) for enabling a Kubernetes/OpenShift deployment, install Docker
Install Httpie
- Install Ory Hydra
- You can use the material provided in this repo to deploy Hydra in Kubernetes
- First, create a namespace called
ory
- Second, install the Database (for instance PostgreSQL) and the Ory Server:
kubectl apply -f ory_install/1-postgresql.yaml
./ory_install/2-oryHelm.sh
- Hydra - Admin API (port 4445)
- In Konnect, create a Gateway Service and a Route to publish the Hydra Administrative API (port 4445). Example of Route: https://api.client.net/admin-idp
- Secure the Route by enabling the OpenId Connect Plugin. Enable the
auth_methods
=client_credentials
andintrospection
- Hydra - Public API (port 4444)
- As the Admin API, configure for the Public API a Gateway Service and a Route without Authenticaton. Example of Route: https://api.client.net/public-idp
2 options are available for the HTTP DCR bridge building:
- AWS Lambda Function
- Docker image (for Kubernetes/OpenShift)
- Create the Function
- Connect to the AWS Console
- Select the proper region (for instance
eu-central-1
) - Create a Lambda function with:
- name =
konnect-portal-dcr-hydra
- runtime =
Node.js 20.x
- Advanced settings / Enable function URL =
enabled
- name =
Click on Create function
- Open the Function
- Change
Code
/Runtime settings
: handler =lambda.handler
- Change
Configuration
/General configuration
: timeout =10s
- Open
Configuration
/Environment variables
and Edit:- HYDRA_ADMIN_API =
<hydra-admin-api-to-be-replaced>
(it's the Hydra Administrative API (4445 port) published through the Kong Gateway, example: https://api.client.net/admin-idp) - HYDRA_TOKEN_AUTHN =
<bearer_jwt_token>
- HYDRA_CLIENT_ID =
<client_id>
- HYDRA_CLIENT_SECRET =
<client_secret>
- KONG_API_TOKENS =
<your_Konnect_API_Key_value>
Put a random strong key value
- HYDRA_ADMIN_API =
Choose one of the both AuthN mechanism: Bearer JWT token or client_id/client_secret. The Lambda Function checks the presence of all variables; so declare all variables even if there is no value.
Click on Save
- Create a S3 bucket and call it for instance
konnect-portal-dcr-hydra
- The purpose of this bucket is to store the source code of the DCR Handler and to push it in the AWS Lambda Function
- You don't need to upload the
lambda-dcr-http.zip
manually: it will be done automatically by the CI workfow
- Build and Push the Docker image for linux/arm64 and linux/amd64
cd konnect-ory-hydra-portal-dcr
docker buildx create --use --platform=linux/amd64,linux/arm64 --name multi-platform-builder
docker buildx build --push --platform linux/amd64,linux/arm64 --tag jeromeguillaume/konnect-ory-hydra-portal-dcr:1.1 .
if you don't want to test locally the Bridge you can skip this section and go to Deploy the HTTP DCR Bridge
2 options are available to run locally HTTP DCR Bridge:
- On the computer OS
- On Docker
The fastify server is started by default on port 3000 for both deployments
- Start HTTP DCR Bridge on the computer OS Install dependencies
yarn install --frozen-lockfile
Create an .env
file at the root of this project, get the following content and replace the strings enclosed by < >:
# it's the Hydra Administrative API (4445 port) published through the Kong Gateway, example: https://api.client.net/admin-idp
HYDRA_ADMIN_API=<hydra-admin-api-to-be-replaced>
# Choose one of the both AuthN mechanism: Bearer JWT token or client_id/client_secret
HYDRA_TOKEN_AUTHN=<bearer_jwt_token>
HYDRA_CLIENT_ID=<client_id>
HYDRA_CLIENT_SECRET=<client_secret>
KONG_API_TOKENS=<your_Konnect_API_Key_value>
Start local instance
yarn start
OR
- Start HTTP DCR Bridge on Docker
docker run -p 3000:3000 -d \
--name konnect-ory-hydra-portal-dcr \
--platform linux/amd64 \
-e "HYDRA_TOKEN_AUTHN=<bearer_jwt_token>" \
-e "HYDRA_CLIENT_ID=<client_id>" \
-e "HYDRA_CLIENT_SECRET=<client_secret>" \
-e "HYDRA_ADMIN_API=<hydra-admin-api-to-be-replaced>" \
-e "KONG_API_TOKENS=<your_Konnect_API_Key_value>" \
jeromeguillaume/konnect-ory-hydra-portal-dcr:1.1
- Create a new Application
- Request: replace
<your_Konnect_API_Key_value>
,<portal_id-to-be-replaced>
,<organization_id-to-be-replaced>
by their proper value. Go on Konnect / Dev Portal to getportal_id
andorganization_id
http POST :3000/ redirect_uris=http://localhost \
x-api-key:<your_Konnect_API_Key_value> \
client_name=jegvscode1 \
application_description=\
grant_types\[\]=authorization_code \
grant_types\[\]=refresh_token \
grant_types\[\]=client_credentials \
grant_types\[\]=implicit \
token_endpoint_auth_method=client_secret_jwt \
portal_id=<portal_id-to-be-replaced> \
organization_id=<organization_id-to-be-replaced>
- Response:
HTTP/1.1 201 Created
...
{
"client_id": "f54b9dc4-ee16-4a99-bfc9-4107ae73d6a4",
"client_id_issued_at": 1705399806,
"client_secret": "istHTAPMMFLRDPT83dPfDCHOZH7cLV6V",
"client_secret_expires_at": 0
}
Check on Hydra the creation of this new client
- Refresh a
client_secret
of an Application
- Request:
http POST :3000/f54b9dc4-ee16-4a99-bfc9-4107ae73d6a4/new-secret x-api-key:<your_Konnect_API_Key_value>
- Response:
HTTP/1.1 200 OK
...
{
"client_id": "f54b9dc4-ee16-4a99-bfc9-4107ae73d6a4",
"client_secret": "JJrUI01URnL863GRyTIIsdFeTrkDVbMj"
}
Check on Hydra the value of the new client_secret
- Delete an Application
- Request:
http DELETE :3000/f54b9dc4-ee16-4a99-bfc9-4107ae73d6a4 x-api-key:<your_Konnect_API_Key_value>
- Response:
HTTP/1.1 204 No Content
Check on Hydra the deletion of this client
- The Git Workflow ci.yml pushes the DCR Handler code in the Lambda Function.
- Prepare and start a
self-hosted
Github Runner: open with the browser your Github repo and select Settings / Actions / Runners and click onNew self-hosted runner
- Create Environment secrets: select Settings / Secrets and variables / Environment secrets with:
- Connect to AWS cli (for the
self-hosted
runner)
aws sso login
- Do a Commit & Push of your repo, check in GitHub the green status of your CI workflow
- Create an
.env
file
- See Test locally the HTTP DCR Bridge for having the content
- Create the Secret
cd konnect-ory-hydra-portal-dcr
kubectl create secret generic sec-konnect-ory-hydra-portal-dcr --from-env-file=.env
- Create the Deployment and Service (as a LoadBlancer) See konnect-ory-hydra-portal-dcr.yaml
kubectl create -f kubernetes/konnect-ory-hydra-portal-dcr.yaml
The results should look like this:
deployment.apps/konnect-portal-dcr-ory-hydra created
service/svc-konnect-portal-dcr-ory-hydra created
Keep in mind that the Bridge listens on HTTP an not HTTPS. The bridge has to be secured by the Kong Gateway
- Get the URL of the Bridge
kubectl get svc svc-konnect-portal-dcr-ory-hydra -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
It's the Bridge Function URL related to <Bridge_Function_url-to-be-replaced>
- Have a Kong Konnect account
- You can Start a Free trial at: konghq.com
- Login to konnect
- Select Gateway Manager menu and open your
Gateway Manager
- Create a new
httpbin
Gateway Service with:
- Name =
httpbin
- Upstream URL =
http://httpbin.apim.eu
Click on Save
- Create a new
httpbin
Route to the Gateway Service with:
- Name =
httpbin
- Path =
/httpbin
Click on Save
- Login to konnect
- Select Dev Portal / Application Auth menu, select DCR Providers tab, click on
+ New DCR Provider
and configure with:
- Name =
DCR Ory Hydra
- Issuer URL =
<hydra-public-api-to-be-replaced>
(example: https://api.client.net/public-idp/.well-known/openid-configuration) - Provider Type =
HTTP
- DCR Base URL =
<Bridge_Function_url-to-be-replaced>
- API Key =
<your_Konnect_API_Key_value>
- Put the same value defined before
- Select Dev Portal / Application Auth menu, click on
+ New Auth Strategy
and configure with:
- Name =
Auth DCR Ory Hydra
- Display Name =
Auth DCR Ory Hydra
- Auth Type =
DCR
- DCR Provider =
DCR Ory Hydra
- Scopes =
openid
- Credential Claims =
client_id
- Auth Method =
bearer
andclient_credentials
Click on Save
- Select API Products menu, click on
+ API Product
and configure with:
- Product Name =
Httpbin
- Select Product Versions menu, click on
+ New Version
and configure with:
- Product Version Name =
v1
Click on Save
- Link with a Gateway Service by cicking on
+ Link
:
- Select Control Plane =
Your Control Plane
stands forGateway Manager
- Gateway Service =
httpbin
Click on Save
- Update the
unpublished
Status topublished
and checkPublish API Product
Click on Save
- Update the
disabled
App Registration toenabled
with:
- Auth Strategy =
Auth DCR Ory Hydra
- App Registration Enabled
-
Login to Konnect Dev Portal
-
Click on
My Apps
under your profile name -
Click on
New App
-
Go on Hydra Server and check the new Client
hydra get client 01c6ea95-7e7a-4d00-92fb-204bbc29b03c --format json-pretty
- Go on Catalog, Select a Service and Register it to the new App
- Test access to the API published on the DevPortal by using the new
client_id
andclient_secret
- Request:
http -a "01c6ea95-7e7a-4d00-92fb-204bbc29b03c:I3gV7EE#CUFqMGBI66_ceeyIbAcwJL" :8000/myhttpbin/anything
- Response:
HTTP/1.1 200 OK
...
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Authorization": "Bearer ABCDEF...."
},
"json": null,
"method": "GET",
"url": "https://localhost/anything"
}
- Test the Refresh secret
- Delete the App
- Go on Hydra Server and check that the client is no longer present
hydra get client 01c6ea95-7e7a-4d00-92fb-204bbc29b03c
see in notes.txt example of commands to call directly Hydra APIs