Skip to content

Latest commit

 

History

History
372 lines (311 loc) · 14.2 KB

README.md

File metadata and controls

372 lines (311 loc) · 14.2 KB

Konnect Portal DCR Handler for Ory Hydra

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

Prerequisites

Fork this repository

Fork this repository

Git clone (your forked repository)

Do a git clone of your forked repository

git clone https://github.com/<**YOUR_NAME**>/konnect-ory-hydra-portal-dcr.git

Yarn

Install Yarn ^1.22.x

Docker

If you want to build a Docker image (for the HTTP DCR bridge) for enabling a Kubernetes/OpenShift deployment, install Docker

Httpie

Install Httpie

Hydra configuration

  1. 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
  1. 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 and introspection
  1. Hydra - Public API (port 4444)

Build the HTTP DCR bridge

2 options are available for the HTTP DCR bridge building:

  • AWS Lambda Function
  • Docker image (for Kubernetes/OpenShift)

AWS Lambda Function

  1. 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

Click on Create function

  1. 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

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

See the Function URL Alt text

AWS S3 Bucket

  • 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 Alt text

Docker image

  • 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 .

Optional: test locally the HTTP DCR Bridge

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

  1. 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


  1. 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
  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 get portal_id and organization_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

  1. 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

  1. 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

Deploy the HTTP DCR Bridge

Deploy the DCR Handler to the Lambda Function

  • 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 on New self-hosted runner
  • Create Environment secrets: select Settings / Secrets and variables / Environment secrets with:
    • Environment: dev with those variables:
      • AWS_ROLE_NAME: <function_arn-to-be-replaced> (example: arn:aws:lambda:eu-west-3:162225303348:function:konnect-portal-dcr-hydra)
      • BUCKET_NAME: konnect-portal-dcr-hydra
      • FUNCTION_NAME: konnect-portal-dcr-hydra Alt text
  • 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

Deploy the Bridge on Kubernetes / OpenShift with the Docker image

  1. Create an .env file
  1. Create the Secret
cd konnect-ory-hydra-portal-dcr
kubectl create secret generic sec-konnect-ory-hydra-portal-dcr --from-env-file=.env
  1. 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

  1. 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>

Konnect Gateway Service configuration

  1. Have a Kong Konnect account
  1. Login to konnect
  2. Select Gateway Manager menu and open your Gateway Manager
  3. Create a new httpbin Gateway Service with:
  • Name = httpbin
  • Upstream URL = http://httpbin.apim.eu

Click on Save

  1. Create a new httpbin Route to the Gateway Service with:
  • Name = httpbin
  • Path = /httpbin

Click on Save

Konnect Dev Portal configuration

  1. Login to konnect
  2. Select Dev Portal / Application Auth menu, select DCR Providers tab, click on + New DCR Provider and configure with:

Click on Save Alt text

  1. 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 and client_credentials

Click on Save

Alt text

  1. Select API Products menu, click on + API Product and configure with:
  • Product Name = Httpbin

Click on Save Alt text

  1. Select Product Versions menu, click on + New Version and configure with:
  • Product Version Name = v1

Click on Save

  1. Link with a Gateway Service by cicking on + Link:
  • Select Control Plane = Your Control Plane stands for Gateway Manager
  • Gateway Service = httpbin

Click on Save

  1. Update the unpublished Status to published and check Publish API Product

Click on Save

  1. Update the disabled App Registration to enabled with:
  • Auth Strategy = Auth DCR Ory Hydra
  • App Registration Enabled

Click on Save Alt text

Test from Konnect Dev Portal the DCR Handler

  1. Login to Konnect Dev Portal

  2. Click on My Apps under your profile name

  3. Click on New App

  4. Set the values as shown and click on Create Alt text

  5. Copy the client_id and client_secret and click on Proceed Alt text

  6. Go on Hydra Server and check the new Client

hydra get client 01c6ea95-7e7a-4d00-92fb-204bbc29b03c --format json-pretty

Alt text

  1. Go on Catalog, Select a Service and Register it to the new App
  2. Test access to the API published on the DevPortal by using the new client_id and client_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"
}
  1. Test the Refresh secret
  • Select My app
  • Select Refresh secret menu Alt text
  1. Delete the App
  • Select My app
  • Select Delete Alt text
  1. Go on Hydra Server and check that the client is no longer present
hydra get client 01c6ea95-7e7a-4d00-92fb-204bbc29b03c 

Alt text

Other material

see in notes.txt example of commands to call directly Hydra APIs