Connect and protect APIs and services
You can use Connectivity Link to protect applications and APIs on existing OpenShift Container Platform clusters and Gateway objects. You can also monitor workloads and the status of OpenShift Container Platform resource metrics and tracing by using observability dashboards and alerts.
- Example tasks
-
-
Configure routes
-
Set up application routes and API definitions and publish them to the cluster.
-
-
Protect applications with Auth policies and allow API access
-
OAuth 2
-
JWT authorization policies
-
API keys
-
Kubernetes tokens
-
Role-based access (RBAC)
-
Relationship-based access control (ReBAC)
-
Open Policy Agent (OPA)
-
-
Observe application and API performance
-
Monitor workloads and the status of OpenShift Container Platform resource metrics and tracing by using observability dashboards and alerts.
-
Ensure that APIs meet performance and availability benchmarks achieved by other data centers by viewing API metrics, such as uptime, requests per second, latency, and errors per minute.
-
-
Allow API access
You can allow users access to your APIs by overriding existing deny-all gateway-level policies. You must also attach application-level AuthPolicy objects and rate-limiting CRs to your HTTPRoute objects.
|
Important
|
The following example allows two users access to the Toystore API by using API keys to authenticate the requests. Other options, such as OpenID Connect, are more appropriate for production use. Use the "least-access" approach that is best for your use case. |
-
Connectivity Link is installed.
-
You configured Connectivity Link policies.
-
You installed the OpenShift CLI (
oc). -
You are logged into OpenShift Container Platform as a cluster administrator.
-
Set the
KUADRANT_SYSTEM_NSenvironment variable based on where you created theKuadrantcustom resource (CR) by running the following command:$ export KUADRANT_SYSTEM_NS=$(oc get kuadrant -A -o jsonpath="{.items[0].metadata.namespace}") -
Create the
Secretcustom resources (CRs), or API keys, for bob and alice users that contain the following information:Example user Secret CRsapiVersion: v1 kind: Secret metadata: name: bob-key namespace: ${KUADRANT_SYSTEM_NS} labels: authorino.kuadrant.io/managed-by: authorino app: toystore annotations: secret.kuadrant.io/user-id: bob stringData: api_key: IAMBOB type: Opaque --- apiVersion: v1 kind: Secret metadata: name: alice-key namespace: ${KUADRANT_SYSTEM_NS} labels: authorino.kuadrant.io/managed-by: authorino app: toystore annotations: secret.kuadrant.io/user-id: alice stringData: api_key: IAMALICE type: Opaque EOF -
Apply the API keys by running the following commands:
$ oc apply -f <bob_key.yaml>Replace
<bob_key.yaml>with the filename you used.$ oc apply -f <alice_key.yaml>Replace
<alice_key.yaml>with the filename you used. -
Create a new
AuthPolicyin a different namespace that overrides thedeny-allpolicy and accepts the API keys. For example, the followingtoystore-auth.yaml:Example userAuthPolicyapiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: toystore-auth namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: toystore defaults: when: - predicate: "request.path != '/health'" rules: authentication: "api-key-users": apiKey: selector: matchLabels: app: toystore credentials: authorizationHeader: prefix: APIKEY response: success: filters: "identity": json: properties: "userid": selector: auth.identity.metadata.annotations.secret\.kuadrant\.io/user-id -
Apply the
AuthPolicyCR by running the following commands:$ oc apply -f <bob_key.yaml>Replace
<bob_key.yaml>with the filename you used.
Service and Deployment objects reference
Before you can create a route to host your application at a public URL, you must create a Service custom resource (CR) as a routing rule. As a best practice, you must also create a Deployment object that is the application pod.
The following is an example of both Deployment and Service CRs for the Toystore example application that you can use as reference in creating your own.
apiVersion: apps/v1
kind: Deployment
metadata:
name: toystore
labels:
app: toystore
spec:
selector:
matchLabels:
app: toystore
template:
metadata:
labels:
app: toystore
spec:
containers:
- name: toystore
image: quay.io/kuadrant/authorino-examples:api
env:
- name: LOG_LEVEL
value: "debug"
- name: PORT
value: "3000"
ports:
- containerPort: 3000
name: http
replicas: 1
---
apiVersion: v1
kind: Service
metadata:
name: toystore
spec:
selector:
app: toystore
ports:
- name: http
port: 80
protocol: TCP
targetPort: 3000
Create an HTTP route for an application
As an application developer, you can create a route to host your application at a public URL.
In Gateway API, use the HTTPRoute custom resource (CR) to specify the routing behavior of HTTP requests from your Gateway object to your application. An HTTPRoute CR is especially useful for multiplexing HTTP or terminated HTTPS connections.
-
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 have access to external or on-premise DNS.
-
You created and applied a
Gatewayobject. -
You have a web application that exposes a port and a TCP endpoint listening for traffic on the port.
-
You created a
Serviceobject for your application. -
You have a local Certificate Authority (CA) bundle.
-
Create an
HTTPRoutecustom resource (CR), such as<toystore>-route.yaml, that has the following information:ExampleHTTPRouteCRapiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: <toystore> namespace: <${KUADRANT_DEVELOPER_NS}> labels: deployment: <toystore> service: <toystore> spec: parentRefs: - name: <${KUADRANT_GATEWAY_NAME}> namespace: <${KUADRANT_GATEWAY_NS}> hostnames: - api.${KUADRANT_ZONE_ROOT_DOMAIN} rules: - matches: - method: GET path: type: PathPrefix value: /cars - method: GET path: type: PathPrefix value: /health backendRefs: - name: <toystore> port: 80-
Replace
<toystore>with the name of your application. -
metadata.namespace: The namespace in which you are deploying your application. Replace <${KUADRANT_DEVELOPER_NS}> with the environment variable you used during installation. -
spec.parentRefs.nameandspec.parentRefs.namespace: The values must match theGatewayobject. -
spec.hostnames: The hostname must match the one specified in theGatewayobject. -
hostname.rules.matches.backendRefs.name: The name of theServicefor your application.
-
-
Apply your
HTTPRouteCR by running the following command:$ oc apply -f <toystore>-route.yamlReplace
<toystore>with the name of your application.Example outputhttproute.gateway.networking.k8s.io/toystore-route createdThe output indicates that the route to the application exists.
-
Verify that the
HTTPRouteis created by running the following command:$ oc get httproute <toystore> -n kuadrant -o=jsonpath='{.status.parents[].conditions[?(@.type=="Accepted")].message}{"\n"}{.status.parents[].conditions[?(@.type=="ResolvedRefs")].message}'Replace
<toystore>with the name of your application.Example outputRoute was valid -
If you have
DNSPolicyandTLSPolicyobjects applied, you can validate that your backend is reachable by running the following command:$ curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}:443/carsNote that the example
TLSPolicyCR uses a self-signedClusterIssuerobject.
Override the low-limit RateLimitPolicy for specific users
When you want to only allow a certain number of requests for specific users to an API that you are developing, and a general limit for all other users, you can override the default low-limit RateLimitPolicy custom resource (CR).
|
Important
|
An existing |
-
You installed Connectivity Link on one or more clusters.
-
If you plan to use rate-limiting in a multicluster environment, you have a shared Redis-based datastore.
-
You installed the OpenShift CLI (
oc). -
You have write access to the OpenShift Container Platform namespaces you need to work with.
-
You have access to external or on-premise DNS.
-
You created a
Gatewayobject. -
You configured your gateway policies and
HTTProutes.
-
Create a new
RateLimitPolicycustom resource (CR) in a different namespace to override the defaultlow-limitpolicy and set rate limits for specific users by using the following example:Example RateLimitPolicy CR for specific usersapiVersion: kuadrant.io/v1 kind: RateLimitPolicy metadata: name: toystore-rlp namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: toystore limits: "general-user": rates: - limit: 5 window: 10s counters: - expression: auth.identity.userid when: - predicate: "auth.identity.userid != 'bob'" "bob-limit": rates: - limit: 2 window: 10s when: - predicate: "auth.identity.userid == 'bob'" -
Apply the CR by running the following command:
$ oc apply -f <toystore-rlp>-
Replace
<toystore-rlp>with the name of your YAML. -
Wait a few minutes for the
RateLimitPolicyCR to be applied.
-
-
Check that the
RateLimitPolicyhas a status ofAcceptedandEnforcedby running the following command:$ oc get ratelimitpolicy -n ${KUADRANT_DEVELOPER_NS} toystore-rlp -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Enforced")].message}' -
Check that the status of the
HTTPRouteis now affected by theRateLimitPolicyCR in the same namespace:$ oc get httproute toystore -n ${KUADRANT_DEVELOPER_NS} -o=jsonpath='{.status.parents[0].conditions[?(@.type=="kuadrant.io/RateLimitPolicyAffected")].message}'
-
Send requests as user alice by running the following command:
$ while :; do curl -k --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMALICE' "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/cars" | grep -E --color "\b(429)\b|$"; sleep 1; doneThe expected outcome is an HTTP status
200every second for 5 seconds, followed by HTTP status429every second for 5 seconds. -
Send requests as user bob by running the following command:
$ while :; do curl -k --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMBOB' "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/cars" | grep -E --color "\b(429)\b|$"; sleep 1; doneThe expected outcome is an HTTP status
200every second for 2 seconds, followed by HTTP status429every second for 8 seconds.
Workflow to configure your Gateway, routes, and policy resources
After you deploy your Gateway object, you must expose endpoints, program your HTTP listener, and secure your connections with policies. You can also apply rate-limiting to ensure performance.
|
Important
|
In multicluster environments, you must perform all of the steps in each cluster individually, unless specifically excluded. |
To complete your deployment, take the following steps:
-
Create and apply a
TLSPolicycustom resource (CR) that uses yourCertificateIssuerobject to set up your HTTPS listener certificates. -
Create and apply an
HTTPRouteorGRPCRouteCR for yourGatewayobject to communicate with your backend application API. -
Create and apply an
AuthPolicyCR to set up a default HTTP403response for any unprotected endpoints.TipUse the
oc explain authpoliciescommand to understand which authentication methods are supported when you use Connectivity Link on OpenShift Container Platform. The in-cluster API documentation lists all supported authentication mechanisms. -
Create and apply a
RateLimitPolicyCR to set up a default artificially low global limit to further protect any endpoints exposed by theGatewayobject. -
Create and apply a
DNSPolicyCR with a load balancing strategy for yourGatewayobject.