Chapter 5. OpenID Connect authentication
You can use OpenID Connect (OIDC) authentication with Connectivity Link to connect and secure an API exposed by a Gateway object.
5.1. Set the OIDC AuthPolicy custom resource Copy linkLink copied to clipboard!
You can configure a Connectivity Link AuthPolicy custom resource (CR) to use an OIDC provider. The same API deployed to multiple clusters can authenticate with the same identity provider.
In a zero-trust environment, every application with an HTTPRoute or GRPCRoute CR exposed by an application developer must also have an attached route-level AuthPolicy CR. You can target either a Gateway or a route object with an AuthPolicy CR.
Prerequisites
- You installed Connectivity Link on one or more clusters.
-
You installed the OpenShift CLI (
oc). - You have write access to the OpenShift Container Platform namespaces you need to work with.
-
You created a
Gatewayobject. -
You created an
HTTPRouteorGRPCRouteobject. - You have a trusted OIDC provider configured to issue tokens for your API clients.
- If your OIDC server is using a self-signed or internal cluster certificate, you injected the trusted CA bundle into your Connectivity Link installation.
Procedure
Create an
AuthPolicyCR that targets anHTTPRouteCR and configures OIDC authentication by using the following example:Example
AuthPolicyCRapiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: <api_oidc_auth> namespace: <user_apps> spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: <api_route> rules: authentication: "oidc-idp-auth": jwt: issuerUrl: "https://rhbk.apps.cluster.example.com/realms/realm"-
The
AuthPolicyCR must exist in the same namespace where theHTTPRouteobject is applied. -
Replace the
spec.metadata.nameparameter value with the name you want to use for yourAuthPolicyCR. -
Replace the
spec.metadata.namespaceparameter value with the namespace where you want yourAuthPolicyCR applied. -
The value of the
spec.targetRef.nameparameter must match the name of yourHTTPRouteobject. -
The URL,
"https://rhbk.apps.cluster.example.com/realms/realm", is the base URL of your OIDC issuer, for example, Red Hat build of Keycloak.
-
The
Apply your
AuthPolicyCR by running the following command:$ oc apply -f <api_oidc_auth.yaml>Replace
<api_oidc_auth.yaml>with yourAuthPolicyYAML filename.
5.1.1. Verify the OIDC AuthPolicy custom resource Copy linkLink copied to clipboard!
You can verify a Connectivity Link AuthPolicy custom resource (CR) after you applied the policy to ensure that it is working as intended.
Prerequisites
- You completed the "Setting the OIDC AuthPolicy custom resource" procedure.
Procedure
Check that your
AuthPolicyhasAcceptedandEnforcedstatus by running the following command:$ oc describe authpolicy <api_oidc_auth> -n <user_apps>-
Replace
<api_oidc_auth>with the name of yourAuthPolicyCR. -
Replace
<user_apps>with the namespace where yourAuthPolicyCR is applied.
Example output
Status: Conditions: Last Transition Time: 2026-06-12T12:00:00Z Message: AuthPolicy has been accepted Reason: Accepted Status: True Type: Accepted Last Transition Time: 2026-06-12T12:00:01Z Message: AuthPolicy has been enforced Reason: Enforced Status: True Type: Enforced-
Replace
Send an unauthenticated request to your route to verify that it is blocked by running the following command:
$ curl -v -s -o /dev/null -w "%{http_code}\n" http://<route_hostname>-
Replace
<route_hostname>with the exposed hostname of your application route.
Example output
HTTP/1.1 401 Unauthorized-
Replace
Send an authenticated request containing a valid OIDC access token to verify that access is granted by running the following command:
$ curl -H "Authorization: Bearer <access_token>" -v -s -o /dev/null -w "%{http_code}\n" http://<route_hostname>-
Replace
<access_token>with a valid JWT string issued by your OIDC provider. -
Replace
<route_hostname>with the exposed hostname of your application route.
Example output
HTTP/1.1 200 OK-
Replace
5.2. Get a token to use with an OIDC AuthPolicy custom resource Copy linkLink copied to clipboard!
After you configured a Connectivity Link AuthPolicy custom resource (CR) to use an OIDC provider, you must get a token.
The following example assumes the following facts:
-
You have a Red Hat build of Keycloak instance running in the
keycloaknamespace that is listening at port8080. -
You have a
kuadrantKeycloak realm. - You have a demonstration OAuth2 client with a Direct Access grant enabled.
-
You have a user
johnwith the passwordp.
Prerequisites
- You installed Connectivity Link on one or more clusters.
-
You installed the OpenShift CLI (
oc). - You have write access to the OpenShift Container Platform namespaces you need to work with.
-
You created a
Gatewayobject. -
You created an
HTTPRouteorGRPCRouteobject. -
You created an
AuthPolicyCR.
Procedure
Get an access token from within the cluster for the user John, who is assigned to the
memberrole, by running the following command:$ ACCESS_TOKEN=$(oc run token --attach --rm --restart=Never -q --image=curlimages/curl -- http://keycloak.keycloak.svc.cluster.local:8080/realms/kuadrant/protocol/openid-connect/token -s -d 'grant_type=password' -d 'client_id=demo' -d 'username=john' -d 'password=p' -d 'scope=openid' | jq -r .access_token)NoteIf your Red Hat build of Keycloak server is reachable from outside the cluster, you can get the token directly. Make sure that the
hostnameset in the OIDC issuer endpoint configured in theAuthPolicyCR matches the one used to get the token and is reachable from within the cluster.
5.3. Use RBAC with an OIDC AuthPolicy custom resource Copy linkLink copied to clipboard!
You can configure role-based-access to use with your OpenID Connect (OIDC) authentication by adding the roles to your AuthPolicy custom resource (CR).
Prerequisites
- You installed Connectivity Link on one or more clusters.
-
You installed the OpenShift CLI (
oc). - You have write access to the OpenShift Container Platform namespaces you need to work with.
-
You created a
Gatewayobject. -
You created an
HTTPRouteorGRPCRouteobject. -
You created an
AuthPolicyCR. - You got a token from your OIDC provider.
Procedure
Add the following roles to your
AuthPolicyCR by using the following example:Example AuthPolicy with RBAC definitions
apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: <api_oidc_rbac_auth> namespace: <user_apps> spec: #... patterns: "member-role": - selector: auth.identity.realm_access.roles operator: incl value: member "admin-role": - selector: auth.identity.realm_access.roles operator: incl value: admin authorization: "rbac-resources-api": when: - cel: "http.path.matches('^/resources(/.)?$')" patternMatching: patterns: - patternRef: member-role "rbac-delete-resource": when: - cel: "http.path.matches('^/resources/\\\\d+$') && http.method == 'DELETE'" patternMatching: patterns: - patternRef: admin-role "rbac-admin-api": when: - cel: "http.path.matches('^/admin(/.)?$')" patternMatching: patterns: - patternRef: admin-role-
Replace the
spec.metadata.nameparameter value with the name you want to use for yourAuthPolicyCR. -
Replace the
spec.metadata.namespaceparameter value with the namespace where you want yourAuthPolicyCR applied. -
Requests to
/resources[/*]require thememberrole. -
DELETErequests to^/resources/\\\\d+$require theadminrole. -
Requests to
^/admin(/.*)?$require theadminrole.
5.3.1. Verify RBAC with OIDC Copy linkLink copied to clipboard!
You can verify that the role-based-access you configured is working your OpenID Connect (OIDC) authentication by conducting tests with different user roles.
The following example assumes the following setup:
- A Red Hat build of Keycloak instance running in the keycloak namespace listening at port 8080.
-
A
kuadrantRed Hat build of Keycloak realm. - An OAuth2 client with Direct Access grant enabled.
-
A user
johnwho is assigned thememberrole and has the passwordp. -
A user
janewho is assigned thememberandadminroles and has the passwordp.
Prerequisites
- You installed Connectivity Link on one or more clusters.
-
You installed the OpenShift CLI (
oc). - You have write access to the OpenShift Container Platform namespaces you need to work with.
-
You created a
Gatewayobject. -
You created an
HTTPRouteorGRPCRouteobject. -
You configured an
AuthPolicyCR with role-based-access.
Procedure
Get an access token from within the cluster for the user John, who is assigned to the
memberrole, by running the following command:$ ACCESS_TOKEN=$(oc run token --attach --rm --restart=Never -q --image=curlimages/curl -- https://keycloak.keycloak.svc.cluster.local:8080/realms/kuadrant/protocol/openid-connect/token -s -d 'grant_type=password' -d 'client_id=demo' -d 'username=john' -d 'password=p' -d 'scope=openid' | jq -r .access_token)NoteIf your Red Hat build of Keycloak server is reachable from outside the cluster, you can get the token directly. Make sure that the
hostnameset in the OIDC issuer endpoint configured in theAuthPolicyCR matches the one used to get the token and is reachable from within the cluster.Retrieve your cluster base domain and assign it to an environment variable by running the following command:
$ export CLUSTER_DOMAIN=$(oc get ingress.config/cluster -o jsonpath='{.spec.domain}')As John, send a
GETrequest to /resources by running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.$CLUSTER_DOMAIN/resources -iExample output
HTTP/1.1 200 OKAs John, send a
DELETErequest to/resources/123by running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -X DELETE https://api.$CLUSTER_DOMAIN/resources/123 -iExample output
HTTP/1.1 403 ForbiddenAs John, send a
GETrequest to/admin/settingsby running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.$CLUSTER_DOMAIN/admin/settings -iExample output
HTTP/1.1 403 ForbiddenGet an access token from within the cluster for the user Jane, who is assigned to the
memberandadminroles by running the following command:$ ACCESS_TOKEN=$(oc run token --attach --rm --restart=Never -q --image=curlimages/curl -- http://keycloak.keycloak.svc.cluster.local:8080/realms/kuadrant/protocol/openid-connect/token -s -d 'grant_type=password' -d 'client_id=demo' -d 'username=jane' -d 'password=p' -d 'scope=openid' | jq -r .access_token)As Jane, send a
GETrequest to/resourcesby running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.$CLUSTER_DOMAIN/resources -iExample output
HTTP/1.1 200 OKAs Jane, send a
DELETErequest to /resources/123 by running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -X DELETE https://api.$CLUSTER_DOMAIN/resources/123 -iExample output
HTTP/1.1 200 OKAs Jane, send a
GETrequest to/admin/settingsby running the following command:$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.$CLUSTER_DOMAIN/admin/settings -iExample output
HTTP/1.1 200 OK