Skip to content

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

OAuth

Page as Markdown

Set up the portal web server to allow dynamic OAuth client registration.

This guide must be completed by a Portal admin.

About this guide

This guide sets up dynamic OAuth client registration for your portal with IdPConnect. Portal users can register an OAuth client directly in the portal frontend to receive a client ID and secret. No driect access to the OIDC provider’s admin UI is required. They can then use the client ID and secret to request an access token from the OIDC provider and authenticate with your APIs.

The following image illustrates the OAuth client registration flow and how users can access an API with an access token.

    %%{init: {"theme": "base", "themeVariables": {"primaryColor": "#cce5ff", "primaryBorderColor": "#3399ff", "primaryTextColor": "#003366", "lineColor": "#3399ff", "edgeLabelBackground": "#e8f4ff", "secondaryColor": "#e8f4ff", "tertiaryColor": "#ffffff", "noteBkgColor": "#e8f4ff", "noteTextColor": "#003366"}}}%%
sequenceDiagram
    actor User as Portal user
    participant Portal as Portal frontend
    participant IdPConnect as IdP Connect
    participant IdP as OIDC provider
    participant Gateway as Portal gateway
    participant App as App

    Note over User,IdP: Register OAuth client
    User->>Portal: Create OAuth credentials for App
    Portal->>IdPConnect: Register client
    IdPConnect->>IdP: Create OAuth client
    IdP-->>IdPConnect: client_id + client_secret
    IdPConnect-->>Portal: client_id + client_secret
    Portal-->>User: Show client_id + client_secret <br/>(one time only)

    Note over User,App: Authenticate and call API
    User->>IdP: POST /token (client_id + client_secret)
    IdP-->>User: access_token
    User->>Gateway: GET /api <br/>(Authorization: Bearer access_token)
    Gateway->>IdP: Validate JWT (JWKS)
    Gateway->>Portal: Check subscription
    Portal-->>Gateway: Approved
    Gateway->>App: Forward request
    App-->>Gateway: Response
    Gateway-->>User: 200 OK
  



OAuth credentials only grant access to ApiProducts that the user’s App is subscribed to and approved for. Users gain access to Apps through their portal Team memberships. You enforce this by applying an OAuth policy to your API routes that chains JWT validation (to verify the token) with portalAuth (to check the subscription).

Before you begin

Portal admins must complete the following tasks:

  1. Set up a portal web server.
  2. Secure the login to the portal frontend.
  3. Optional: Set up a backing database for your portal. This database is used to store the OAuth client credentials that your users create in the Portal frontend app.

Step 1: Set up IdP Connect

IdP Connect is a service that sits between the portal and your OIDC provider. When a portal user creates OAuth credentials, IdP Connect dynamically registers an OAuth client in the OIDC provider on their behalf and returns the client ID and secret to the user.

Deploy the IdP Connect service to your cluster by using Helm.

  1. Add the IdP Connect Helm repo.

    helm repo add gloo-portal-idp-connect https://storage.googleapis.com/gloo-mesh-enterprise/gloo-portal-idp-connect
  2. Deploy IdP Connect to your cluster. Use the realm, Keycloak client and secret that you set up before you began. For other settings, see the IdP Connect public GitHub repo.

    helm upgrade -i -n kgateway-system \
      portal-idp gloo-portal-idp-connect/gloo-portal-idp-connect \
      --version 0.5.2 \
      -f -<<EOF
    connector: keycloak
    keycloak:
      realm: $KEYCLOAK_URL/realms/portal
      mgmtClientId: $KEYCLOAK_CLIENT
      mgmtClientSecret: $KEYCLOAK_SECRET
    EOF
  3. Verify that the deployment completes.

    kubectl -n kgateway-system rollout status deploy gloo-portal-idp-connect
  4. Update the PortalParameters resource to point to your IdP Connect instance.

    kubectl apply -f- <<EOF
    apiVersion: portal.solo.io/v1alpha1
    kind: PortalParameters
    metadata:
      name: portal-params
      namespace: default
    spec:
      store:
        memory: {}
      idpServerURL: http://idp-connect.kgateway-system.svc.cluster.local:80
    EOF
  5. Verify that the portal web server successfully restarted and is up and running.

    kubectl get pods | grep my-portal

Step 2: Create an OAuth policy

Create an OAuth policy to protect your ApiProducts. This way, users must provide credentials from the connected IdP in order to access the underlying APIs that they have access to through the Portal.

  1. In your IdP’s .well-known/openid-configuration endpoint, get the jwks_uri endpoint. In Keycloak, this endpoint is $KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/certs.

  2. Create an AuthConfig that chains together OAuth2 access token validation and PortalAuth. This way, the portal gateway can authorize requests along the routes to your ApiProducts by using the access token from the Authorization: Bearer header.

    kubectl apply -f- <<EOF                               
    apiVersion: extauth.solo.io/v1
    kind: AuthConfig
    metadata:
      name: httpbin-auth
      namespace: default
    spec:
      configs:
        - name: oauth2Validation
          oauth2:
            accessTokenValidation:
              jwt:
                remoteJwks:
                  url: "$KEYCLOAK_URL/realms/portal/protocol/openid-connect/certs"
        - name: httpbinAuth
          portalAuth:
            url: http://portal-my-portal.default.svc.cluster.local:8080
    EOF

    Review the following table to understand this configuration.

    SettingDescription
    name: oauth2ValidationA unique name for each config section in your AuthConfig. The example uses oauth2Validation for the oauth2 section.
    oauth2.accessTokenValidationValidates the access token on incoming requests. The example uses the remote JSON Web Key Set (JWKS) endpoint from your IdP to validate the token signature.
    jwt.remoteJwks.urlThe JWKS endpoint of your IdP. This endpoint is used to verify the token signature. In Keycloak, this is $KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/certs. Make sure to use the same value that you found in your IdP’s .well-known/openid-configuration.
    name: httpbinAuthA unique name for each config section in your AuthConfig. The example uses httpbinAuth for the portalAuth section.
    portalAuthChecks that the OAuth client from the validated token has an approved subscription to the ApiProduct. Must be chained after oauth2.accessTokenValidation so that the Bearer token is already validated before the subscription check.
    portalAuth.urlThe internal Kubernetes service URL of the portal backend server. Replace portal-my-portal with the name of your portal backend service.
  3. Create an EnterpriseKgatewayTrafficPolicy that references the AuthConfig and applies the config to httpbin’s HTTPRoute. You also include a CORS policy that allows requests from a different origin to the httpbin API.

    kubectl apply -f- <<EOF   
    apiVersion: enterprisekgateway.solo.io/v1alpha1
    kind: EnterpriseKgatewayTrafficPolicy
    metadata:
      name: httpbin-auth
      namespace: default
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: httpbin-route
      entExtAuth:
        authConfigRef:
          name: httpbin-auth
          namespace: default
      cors:
        allowCredentials: true
        allowHeaders:
          - "*"
        allowMethods:
          - GET
        allowOrigins:
          - "*"
    EOF
  4. Test that the httpbin app is protected.

    curl -vik ${INGRESS_GW_ADDRESS}:8080/httpbin/headers -H "host: api.example.com" 
    curl -vik localhost:8080/httpbin/headers -H "host: api.example.com" 

    Example output:

    * Request completely sent off
    < HTTP/1.1 403 Forbidden
    HTTP/1.1 403 Forbidden
    < server: envoy
    server: envoy
    < content-length: 0
    content-length: 0
    < 
    
    * Connection #0 to host localhost left intact

Next steps

Was this page helpful?