Este contenido no está disponible en el idioma seleccionado.

Chapter 1. Configuring and deploying gateway policies


You can use Connectivity Link to connect and secure an API exposed by a Gateway object.

1.1. Secure, protect, and connect APIs

You can use Connectivity Link on OpenShift Container Platform to connect an API that you expose by a applying Gateway object. Ingress is handled by Gateway API. You must also add a DNS provider secret, TLS and other policies to secure your connections, and use an HTTP route object to define the flow of traffic.

Connectivity Link draws on the user-role concepts of Gateway API, for example:

  • Platform engineers: Generally in charge of OpenShift Container Platform infrastructure, platform engineers create and secure Gateway objects with associated policies that application developers use to deploy APIs.
  • Application developers: Application developers create the applications used on OpenShift Container Platform, and can override the gateway-level global authorization and rate-limiting policies to configure application-level requirements for specific users.

1.1.1. Set up your environment

You can set up your environment variables and deploy an application on your OpenShift Container Platform cluster. In this example, a demonstration application is used.

Note

The Toystore application is an example only and is not intended for production use.

Prerequisites

  • You installed Connectivity Link on at least one OpenShift Container Platform cluster.
  • 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 know the name and namespace of the gateway you want to connect your application to.

Procedure

  1. Set the following environment by running the following command:

    $ export KUADRANT_GATEWAY_NS=api-gateway \
      export KUADRANT_GATEWAY_NAME=ingress-gateway \
      export KUADRANT_DEVELOPER_NS=toystore \
      export KUADRANT_AWS_ACCESS_KEY_ID=xxxx \
      export KUADRANT_AWS_SECRET_ACCESS_KEY=xxxx \
      export KUADRANT_ZONE_ROOT_DOMAIN=example.com \
      export KUADRANT_CLUSTER_ISSUER_NAME=self-signed
    • KUADRANT_GATEWAY_NS: Namespace for your gateway in OpenShift Container Platform.
    • KUADRANT_GATEWAY_NAME: Name of your gateway in OpenShift Container Platform.
    • KUADRANT_DEVELOPER_NS: Namespace for the example Toystore app in OpenShift Container Platform. You can replace this value with the name of the application you want to use.
    • KUADRANT_AWS_ACCESS_KEY_ID: DNS provider access key ID. In this example, AWS is used. You can replace this value with your DNS provider information.
    • KUADRANT_AWS_SECRET_ACCESS_KEY: DNS provider secret access key with permissions to manage your DNS zone. In this example, AWS is used. You can replace this value with your DNS provider information.
    • KUADRANT_ZONE_ROOT_DOMAIN: The root domain associated with your DNS zone ID. In this example, the OpenShift Container Platform secret containing the credentials for the DNS provider is AWS Route53. You can replace this value with your DNS provider information.
    • KUADRANT_CLUSTER_ISSUER_NAME: Name of the certificate authority or issuer TLS certificates.
  2. Create the namespace for the application by running the following command:

    $ oc create ns ${KUADRANT_DEVELOPER_NS}
  3. Deploy your application to the namespace you specified by running the following command:

    $ oc apply -f https://raw.githubusercontent.com/Kuadrant/Kuadrant-operator/main/examples/toystore/toystore.yaml -n ${KUADRANT_DEVELOPER_NS}

    You can replace the Toystore application with the path to the one you want to use.

1.1.2. Setting up a DNS provider secret

As a platform engineer, you can create access to the DNS zones that Connectivity Link can use by configuring your external DNS provider credentials. After setting up your Secret custom resource (CR), restrict access to only the DNS zones that you want Connectivity Link to manage by setting a DNSPolicy CR.

Important

You must apply the following Secret CR to each cluster.

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 have access to external or on-premise DNS.

Procedure

  1. Create the namespace you want your Gateway CR deployed in by running the following command:

    $ oc create ns ${KUADRANT_GATEWAY_NS}
  2. Create the secret credentials in the same namespace as the gateway namespace by running the following command:

    $ oc -n ${KUADRANT_GATEWAY_NS} create secret generic <aws-credentials> \
      --type=kuadrant.io/aws \
      --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \
      --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY

    Replace <aws-credentials> with the secret you want to use.

Next step

  • Configure your TLS issuer and policy.

1.1.3. Create your Gateway object

As a platform engineer or cluster administrator, you must deploy a Gateway object in your OpenShift Container Platform cluster to begin setting up the infrastructure used by application developers. The Gateway is the instantiation of your entry point. It tells the controller to provision load balancer with specific ports and security credentials.

Important

In a multicluster environment, for Connectivity Link to balance traffic by using DNS across clusters, you must define your Gateway object with a shared hostname. You can define this by using an HTTPS listener with a wildcard hostname based on the root domain. You must apply these resources to each cluster that you want to use them.

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 have access to external or on-premise DNS.

Procedure

  1. Create a Gateway custom resource (CR), such as {KUADRANT_GATEWAY_NAME}.yaml, that has the following information:

    Example Gateway CR

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: ${KUADRANT_GATEWAY_NAME}
      namespace: ${KUADRANT_GATEWAY_NS}
      labels:
        kuadrant.io/gateway: "true"
    spec:
        gatewayClassName: openshift-default
        listeners:
        - allowedRoutes:
            namespaces:
              from: All
          hostname: "api.${KUADRANT_ZONE_ROOT_DOMAIN}"
          name: api
          port: 443
          protocol: HTTPS
          tls:
            certificateRefs:
            - group: ""
              kind: Secret
              name: api-${KUADRANT_GATEWAY_NAME}-tls
            mode: Terminate

    Important

    In a multicluster environment, for Connectivity Link to balance traffic by using DNS across clusters, you must specify a gateway with a shared hostname. You can define this by using an HTTPS listener with a wildcard hostname based on the root domain.

  2. Apply the Gateway CR by running the following command:

    $ oc apply -f {KUADRANT_GATEWAY_NAME}.yaml

Verification

  1. Check the status of your Gateway object by running the following command:

    $ oc get gateway ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Programmed")].message}'

    Example output

    Resource accepted
    Resource programmed, assigned to service(s) ${KUADRANT_GATEWAY_NAME}.${KUADRANT_GATEWAY_NS}.svc.cluster.local:443

  2. Check the status of your HTTPS listener by running the following command:

    $ oc get gateway ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.listeners[0].conditions[?(@.type=="Programmed")].message}'

    The HTTPS listener exists, but is not programmed or ready to accept traffic because you do not have valid certificates available.

Next step

  • Create a TLSPolicy CR to program your HTTPS listener to accept traffic.

1.2. About configuring your Gateway policies and HTTP route

As a platform engineer or cluster administrator, you must expose endpoints and program your HTTPS listener after you deploy your Gateway object. Next, take the following steps:

  • Create and apply a TLSPolicy custom resource (CR) that uses your CertificateIssuer object to set up your HTTPS listener certificates.
  • Create and apply an HTTPRoute CR for your Gateway object to communicate with your backend application API.
  • Create and apply an AuthPolicy CR to set up a default HTTP 403 response for any unprotected endpoints
  • Create and apply a RateLimitPolicy CR to set up a default artificially low global limit to further protect any endpoints exposed by the Gateway object.
  • Create and apply a DNSPolicy CR with a load balancing strategy for your Gateway object.
Important

In multicluster environments, you must perform all of the steps in each cluster individually, unless specifically excluded.

1.2.1. Add a TLS certificate issuer

To secure communication to your Gateway object, you must define a certificate authority (CA) as an issuer for TLS certificates. Configure a TLSPolicy CR to automatically provision TLS certificates based on Gateway object listener hosts by using integration with cert-manager Operator for Red Hat OpenShift and ACME providers.

Note

You can use any certificate issuer supported by cert-manager. In multicluster environments, you must add your TLS issuer in each OpenShift Container Platform cluster.

If you set up your Gateway CR to use HTTP instead of than HTTPS, setting up TLS and a TLSPolicy CR are not required.

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 have access to external or on-premise DNS.
  • You created and applied a Gateway object.
  • You created and applied an HTTPRoute object.

Procedure

  1. Before adding a TLS certificate issuer, create the secret credentials in the cert-manager namespace by running the following command:

    $ oc -n cert-manager create secret generic <dns-provider-credentials> \
      --type=kuadrant.io/aws \
      --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \
      --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY

    Replace <dns-provider-credentials> with the secret you want to use. This example uses Amazon Web Services (AWS).

  2. Create a TLS certificate issuer resource, such as {KUADRANT_CLUSTER_ISSUER_NAME}.yaml, that has the following information:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: ${KUADRANT_CLUSTER_ISSUER_NAME}
    spec:
      selfSigned: {}
  3. Apply the ClusterIssuer CR by running the following command:

    $ oc apply -f {KUADRANT_CLUSTER_ISSUER_NAME}.yaml

Verification

  • Verify that the ClusterIssuer object is ready by running the following command:

    $ oc wait clusterissuer/${KUADRANT_CLUSTER_ISSUER_NAME} --for=condition=ready=true

1.2.2. Setting a TLS policy

Create a TLSPolicy custom resource (CR) for your gateway to regulate the ciphers a client can use when connecting to the server. This ensures that Connectivity Link components use cryptographic libraries that do not allow known insecure protocols, ciphers, or algorithms.

If you set up your Gateway CR to use HTTP instead of than HTTPS, setting up TLS and a TLSPolicy CR are not required.

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 have access to external or on-premise DNS.
  • You created and applied a Gateway object.

Procedure

  1. Create a TLSPolicy custom resource (CR) such as <toystore_tls.yaml>, that has the following information:

    Example TLSPolicy CR

    apiVersion: kuadrant.io/v1
    kind: TLSPolicy
    metadata:
      name: ${KUADRANT_GATEWAY_NAME}-tls
      namespace: ${KUADRANT_GATEWAY_NS}
    spec:
      targetRef:
        name: ${KUADRANT_GATEWAY_NAME}
        group: gateway.networking.k8s.io
        kind: Gateway
      issuerRef:
        group: cert-manager.io
        kind: ClusterIssuer
        name: ${KUADRANT_CLUSTER_ISSUER_NAME}

  2. Apply your TLSPolicy CR by running the following command:

    $ oc apply -f <toystore_tls.yaml>

    Replace <toystore> with the name of your TLSPolicy object.

Verification

  • Verify that your TLSPolicy object has an Accepted and Enforced status by running the following command:

    $ oc get tlspolicy ${KUADRANT_GATEWAY_NAME}-tls -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Enforced")].message}'

    This might take a few minutes.

    Example output

    TLSPolicy has been accepted
    TLSPolicy has been successfully enforced

1.2.3. Setting the DNS policy

Control multicluster ingress by using DNS to bring traffic to your gateways with DNSPolicy custom resources (CRs). Setting a DNS policy automates the link between your Gateway IP address and a human-readable hostname.

Create and apply a default DNSPolicy custom resource (CR) to ensure consistency and cleanup. You can standardized naming by creating a pattern for developers who need URLs, manage time-to-live values, and set up automatic cleanup of unused DNS records.

Prerequisites

  • You installed Connectivity Link on at least one OpenShift Container Platform cluster.
  • 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 DNS-provider Secret object.
  • You created a Gateway object.

Procedure

  1. Create a DNSPolicy custom resource (CR), for example, {KUADRANT_GATEWAY_NAME}-dnspolicy.yaml, that includes the following information:

    apiVersion: kuadrant.io/v1
    kind: DNSPolicy
    metadata:
      name: <${KUADRANT_GATEWAY_NAME}-dnspolicy>
      namespace: <${KUADRANT_GATEWAY_NS}>
    spec:
      healthCheck:
        failureThreshold: 3
        interval: 1m
        path: /health
      loadBalancing:
        defaultGeo: true
        geo: GEO-NA
        weight: 120
      targetRef:
        name: <${KUADRANT_GATEWAY_NAME}>
        group: gateway.networking.k8s.io
        kind: Gateway
      providerRefs:
      - name: <dns_provider_credentials>
    • Replace <{KUADRANT_GATEWAY_NAME}-dnspolicy.yaml> with the environment variable you defined.
    • Replace <{KUADRANT_GATEWAY_NS}> with the environment variable you defined.
    • spec.loadBalancing.geo: Defines a geographically relevant load balancer. In this example, GEO-NA is used. Change this to match your requirements.
    • spec.providerRefs: Replace <dns_provider_credentials> with a reference to the OpenShift Container Platform secret containing the credentials for your DNS provider.
  2. Apply the DNSPolicy CR by running the following command:

    $ oc apply -f <{KUADRANT_GATEWAY_NAME}-dnspolicy.yaml> -n <gateway-namespace>
    • Replace <{KUADRANT_GATEWAY_NAME}-dnspolicy.yaml> with the filename you used.
    • Replace <gateway-namespace> with name of the OpenShift Container Platform namespace that contains the gateway.

Verification

  1. Verify that your DNSPolicy object has a status of Accepted and Enforced by running the following command:

    $ oc get dnspolicy <${KUADRANT_GATEWAY_NAME}-dnspolicy> -n <${KUADRANT_GATEWAY_NS}> -o=jsonpath='{.status.conditions[?(@.type=="SubResourcesHealthy")].message}'
    • Replace <{KUADRANT_GATEWAY_NAME}-dnspolicy.yaml> with the filename you used.
    • Replace <{KUADRANT_GATEWAY_NS}> with the environment variable you used.
    • This process might take a few minutes.
  2. Check the status of the DNS health checks that are enabled on your DNS policy by running the following command:

    $ oc get dnspolicy <${KUADRANT_GATEWAY_NAME}-dnspolicy> -n <${KUADRANT_GATEWAY_NS}> -o=jsonpath='{.status.conditions[?(@.type=="SubResourcesHealthy")].message}'
    • Replace <{KUADRANT_GATEWAY_NAME}-dnspolicy.yaml> with the filename you used.
    • Replace <{KUADRANT_GATEWAY_NS}> with the environment variable you used.
    • These health checks flag a published endpoint as healthy or unhealthy based on the defined configuration. When unhealthy, an endpoint is not published if it has not already been published to the DNS provider. An endpoint is only unpublished if it is part of an A record that has multiple values. You can see endpoint status in all cases in the DNSPolicy object status.

1.2.4. Setting the default AuthPolicy

As a platform engineer you can use Auth policy objects to define who you allow to connect. Configure a Connectivity Link AuthPolicy custom resource (CR) to use external auth providers. You can ensure that different clusters exposing the same API can authenticate with the same permissions.

Tip

Apply an AuthPolicy custom resource (CR) with a deny-all policy to create a zero-trust environment. Using a zero-trust AuthPolicy object means that no traffic flows unless a specific allow rule is set. Every connection request must be authenticated. You can prevent the accidental exposing of services by using a deny-all policy.

In a zero-trust environment, every application with an HTTPRoute exposed by an application developer must also have an attached route-level AuthPolicy CR. You can attach multiple AuthPolicy objects to your Gateway and HTTPRoute CRs.

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 have access to external or on-premise DNS.
  • You created a Gateway object.
  • You created an HTTPRoute object.

Procedure

  1. Create a default AuthPolicy CR, such as gateway_name-auth.yaml, with a deny-all setting for your Gateway object:

    Example AuthPolicy CR

    apiVersion: kuadrant.io/v1
    kind: AuthPolicy
    metadata:
      name: ${KUADRANT_GATEWAY_NAME}-auth
      namespace: ${KUADRANT_GATEWAY_NS}
    spec:
      targetRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: ${KUADRANT_GATEWAY_NAME}
      defaults:
       when:
         - predicate: "request.path != '/health'"
       rules:
        authorization:
          deny-all:
            opa:
              rego: "allow = false"
        response:
          unauthorized:
            headers:
              "content-type":
                value: application/json
            body:
              value: |
                {
                  "error": "Forbidden",
                  "message": "Access denied by default by the gateway operator. If you are the administrator of the service, create a specific auth policy for the route."
                }

  2. Apply your HTTPRoute CR by running the following command:

    $ oc apply -f <gateway_name-auth.yaml>
    • Replace <gateway_name-auth.yaml> with the name of your HTTPRoute CR.

Verification

  1. Check that your AuthPolicy has Accepted and Enforced status by running the following command:

    $ oc get authpolicy ${KUADRANT_GATEWAY_NAME}-auth -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Enforced")].message}'

    Example output

    AuthPolicy has been accepted
    AuthPolicy has been successfully enforced

  2. Test your AuthPolicy by running the following curl command:

    $ curl -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://talker-api.127.0.0.1.nip.io:8000/hello

    Example output

    HTTP/1.1 200 OK

1.2.5. Setting a default rate-limit policy

As a platform engineer, set up rate limiting to ensure that you are defining how much any one service can use the Gateway object’s connection resources. Rate limits also protect backend services from excessive requests. You can attach multiple RateLimitPolicy objects to your Gateway and HTTPRoute CRs.

Prerequisites

  • You installed Connectivity Link on one or more clusters.
  • 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 Gateway object.
  • You created an HTTPRoute object.

Procedure

  1. Create a default RateLimitPolicy custom resource (CR), for example, gateway_name-rlp.yaml, that has the following information:

    Example RateLimitPolicy CR

    apiVersion: kuadrant.io/v1
    kind: RateLimitPolicy
    metadata:
      name: ${KUADRANT_GATEWAY_NAME}-rlp
      namespace: ${KUADRANT_GATEWAY_NS}
    spec:
      targetRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: ${KUADRANT_GATEWAY_NAME}
      defaults:
        limits:
          "low-limit":
            rates:
            - limit: 1
              window: 10s

    • A low-limit value is used in this example for the ease of testing the CR. Configure the spec.defaults.limits: values that makes in your use case.
  2. Apply your RateLimitPolicy CR by running the following command:

    $ oc apply -f <gateway_name-rlp.yaml>
    • Replace <gateway_name-rlp.yaml> with the name of your RateLimitPolicy YAML.

Verification

  1. Check that your RateLimitPolicy has Accepted and Enforced status by running the following command:

    $ oc get ratelimitpolicy ${KUADRANT_GATEWAY_NAME}-rlp -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Enforced")].message}'

    Example output

    RateLimitPolicy has been accepted
    RateLimitPolicy has been successfully enforced

  2. Test your rate-limiting by running the following curl command:

    $ while :; do curl -k --write-out '%{http_code}\n' --silent --output /dev/null  "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/cars" | grep -E --color "\b(429)\b|$"; sleep 1; done

    HTTP 403 responses are expected.

1.2.6. Adding rate-limit headers to an API response

When you need to ensure that your traffic remains stable under heavy load, you can add rate-limit headers to your API responses.

By adding x-ratelimit-* headers, you can turn your APIs into self-documenting systems that can proactively throttle their own request frequency and time their retries. You can simplify debugging for developers and reduce unnecessary traffic spikes.

Prerequisites

  • 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 Gateway object.
  • You configured your gateway policies and HTTP routes.
  • You applied a default RateLimitPolicy CR to your deployment.
  • You have write access to the namespace where Connectivity Link is installed.

Procedure

  1. Find the name of the Limitador CR in your cluster by running the following command:

    $ oc get limitador -A
  2. Apply a patch to add headers to the CR by running the following command:

    $ oc patch limitador limitador -n KUADRANT-NAMESPACE --type=merge -p '{"spec": {"rateLimitHeaders": "DRAFT_VERSION_03"}}'

Verification

  • Test for the presence of headers by running the following command:

    $ curl -i -X GET http://<gateway_url>/path

    Replace <gateway_url> with the URL of your Gateway object.

    Example output

    HTTP/1.1 200 OK
    x-ratelimit-limit: 5, 5;w=60
    x-ratelimit-remaining: 4
    x-ratelimit-reset: 58

1.3. About token-based rate limiting with TokenRateLimitPolicy

As an application developer, you can use a TokenRateLimitPolicy custom resource (CR) to enforce rate limits based on token consumption rather than the number of requests.

This policy extends the Envoy Rate Limit Service (RLS) protocol with automatic token usage extraction. It is particularly useful for protecting Large Language Model (LLM) APIs, where the cost and resource usage correlate more closely with the number of tokens processed.

TokenRateLimitPolicy counts tokens by extracting usage metrics in the body of the artificial intelligence (AI) inference API call, allowing for finer-grained control over API usage based on actual workload.

1.3.1. How token rate limiting works

The TokenRateLimitPolicy object tracks cumulative token usage per client. Before forwarding a request, it checks whether the client has already exceeded their limit. After the upstream responds, the policy extracts the actual token cost and updates the client’s counter.

For example:

  1. On an incoming request, the gateway evaluates the matching rules and predicates from the TokenRateLimitPolicy resources.
  2. If the request matches, the gateway prepares the necessary rate limit descriptors and monitors the response.
  3. After receiving the response, the gateway extracts the usage.total_tokens field from the JSON response body.
  4. The gateway then sends a RateLimitRequest to Limitador, including the actual token count as a hits_addend.
  5. Limitador tracks the cumulative token usage and responds to the gateway with OK or OVER_LIMIT.

1.3.2. Key features and use cases

  • Enforces limits based on token usage by extracting the usage.total_tokens field from an OpenAI-style inference JSON response body.
  • Suitable for consumption-based APIs such as LLMs where the cost is tied to token counts.
  • Allows defining different limits based on criteria such as user identity, API endpoints, or HTTP methods.
  • Works with AuthPolicy to apply specific limits to authenticated users or groups.
  • Inherits functionalities from RateLimitPolicy, including defining multiple limits with different durations and using Redis for shared counters in multicluster environments.

1.3.3. Integrating with AuthPolicy

You can combine TokenRateLimitPolicy with AuthPolicy to apply token limits based on authenticated user identity. When an AuthPolicy successfully authenticates a request, it injects identity information that is used by the TokenRateLimitPolicy to select the appropriate limit.

For example, you can define different token limits for users belonging to differently tiered groups, identified using claims in a JWT-validated by AuthPolicy.

1.3.4. Configuring token-based rate limiting for LLM APIs

You can protect Large Language Model (LLM) APIs deployed on OpenShift Container Platform by configuring a TokenRateLimitPolicy custom resource (CR) that you integrate with an AuthPolicy object for user-specific limits.

Prerequisites

  • You installed Connectivity Link on the OpenShift Container Platform cluster you are working with.
  • Gateway and HTTPRoute objects are both configured to expose your service.
  • You created and applied an AuthPolicy custom resource (CR) that overrides the default deny-all setting.
  • If you are running in a multicluster setup, or requiring persistent counters, Redis is configured for the Limitador Operator component.
  • Your configured your upstream service to return an OpenAI-compatible JSON response containing a usage.total_tokens field in the response body.

Procedure

  1. Create a TokenRateLimitPolicy YAML, for example, tokenratelimitpolicy.yaml that includes the following information:

    Example TokenRateLimitPolicy YAML

    apiVersion: kuadrant.io/v1alpha1
    kind: TokenRateLimitPolicy
    metadata:
      name: llm-protection
    spec:
      targetRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: ai-gateway
      limits:
        free-users:
          rates:
            - limit: 10000
              window: 24h
          when:
            - predicate: request.path == "/v1/chat/completions"
            - predicate: |
                auth.identity.groups.split(",").exists(g, g == "free")
          counters:
            - expression: auth.identity.userid
        pro-users:
          rates:
            - limit: 100000
              window: 24h
          when:
            - predicate: request.path == "/v1/chat/completions"
            - predicate: |
                auth.identity.groups.split(",").exists(g, g == "pro")
          counters:
            - expression: auth.identity.userid

    • Choose a filename for the policy that makes sense in your environment.
    • spec.limits.free-users.rates.limit: 10,000 tokens per day for free tier.
    • spec.limits.free-users.when.predicate: Set to inference traffic only.
    • pro-users.rates.limit: 100,000 per day for the pro user.
    • spec.limits.pro-users.when.predicate: Set to inference traffic only.
  2. Apply the TokenRateLimitPolicy policy by running the following command:

    $ oc apply -f <tokenratelimitpolicy.yaml> -n <gateway_namespace>

    Replace <tokenratelimitpolicy.yaml> with the filename you used. Replace <gateway-namespace> with your gateway namespace.

  3. Check the status of the policy to ensure it was accepted and enforced on the target HTTPRoute. Look for conditions with type: Accepted and type: Enforced with status: "True".

    $ oc get <tokenratelimitpolicy.yaml> llm-protection -n <gateway-namespace> -o jsonpath='{.status.conditions}'

    Replace <tokenratelimitpolicy.yaml> with the filename you used. Replace <gateway_namespace> with your gateway namespace.

  4. Send requests to your API endpoint, including the required authentication details, by running the following command:

    $ curl -H "Authorization: <auth_policy>" \
         -d '{"model": "gpt-4", "messages": [{"role": "user", "content": "Hello"}]}' \
         <api_endpoint>

    Replace <auth_policy> and <api_endpoint> with your values.

Verification

  • Ensure that your upstream service responds with an OpenAI-compatible JSON body containing the usage.total_tokens field.
  • Requests made when the client is within their token limits should receive a 200 OK response or other success status and their token counter is updated.
  • Requests made when the client has already exceeded their token limits should receive a 429 Too Many Requests response.

1.4. Override your gateway policies for auth and rate limiting

As an application developer, you can allow users access to your API by overriding existing deny-all gateway-level policies. You must attach application-level AuthPolicy objects and rate-limiting CRs to your HTTPRoute objects.

Important

The following example allows two users authenticated access to the Toystore API. The following example uses API keys to authenticate the requests. Other options, such as OpenID Connect, might be more appropriate for production use. Use the "least-access" approach that is best for your use case.

Prerequisites

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

Procedure

  1. Set the KUADRANT_SYSTEM_NS environment variable based on where you created the Kuadrant custom resource (CR) by running the following command:

    $ export KUADRANT_SYSTEM_NS=$(oc get kuadrant -A -o jsonpath="{.items[0].metadata.namespace}")
  2. Create the Secret custom resources (CRs), or API keys, for bob and alice users that contain the following information:

    Example user Secret CRs

    apiVersion: 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

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

  4. Create a new AuthPolicy in a different namespace that overrides the deny-all policy and accepts the API keys. For example, the following toystore-auth.yaml:

    Example user AuthPolicy

    apiVersion: 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

  5. Apply the AuthPolicy CR by running the following commands:

    $ oc apply -f <bob-key.yaml>

    Replace <bob-key.yaml> with the filename you used.

1.4.1. About Service and Deployment objects

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.

Example application Deployment and Service CRs

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:talker-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

1.4.2. Creating 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.

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 have access to external or on-premise DNS.
  • You created and applied a Gateway object.
  • You have a web application that exposes a port and a TCP endpoint listening for traffic on the port.
  • You created a Service object for your application.
  • You have a local Certificate Authority (CA) bundle.

Procedure

  1. Create an HTTPRoute custom resource (CR), such as <toystore>-route.yaml, that has the following information:

    Example HTTPRoute CR

    apiVersion: 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.name and spec.parentRefs.namespace: The values must match the Gateway object.
    • spec.hostnames: The hostname must match the one specified in the Gateway object.
    • hostname.rules.matches.backendRefs.name: The name of the Service for your application.
  2. Apply your HTTPRoute CR by running the following command:

    $ oc apply -f <toystore>-route.yaml

    Replace <toystore> with the name of your application.

    Example output

    httproute.gateway.networking.k8s.io/toystore-route created

    The output indicates that the route to the application exists.

Verification

  1. Verify that the HTTPRoute is 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 output

    Route was valid

  2. If you have DNSPolicy and TLSPolicy objects applied, you can validate that your backend is reachable by running the following command:

    $ curl -k  https://api.${KUADRANT_ZONE_ROOT_DOMAIN}:443/cars

    Note that the example TLSPolicy CR uses a self-signed ClusterIssuer object.

1.4.3. Overriding 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 Gateway-level policy affects new HTTPRoute objects. Because you want users to now access this API, you must override that Gateway policy. For simplicity, you can use API keys to authenticate the requests, but other options such as OpenID Connect are also available.

Prerequisites

  • 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 Gateway object.
  • You configured your gateway policies and HTTP routes.

Procedure

  1. Create a new RateLimitPolicy custom resource (CR) in a different namespace to override the default low-limit policy and set rate limits for specific users by using the following example:

    Example RateLimitPolicy CR for specific users

    apiVersion: 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'"

  2. 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 RateLimitPolicy CR to be applied.
  3. Check that the RateLimitPolicy has a status of Accepted and Enforced by 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}'
  4. Check that the status of the HTTPRoute is now affected by the RateLimitPolicy CR in the same namespace:

    $ oc get httproute toystore -n ${KUADRANT_DEVELOPER_NS} -o=jsonpath='{.status.parents[0].conditions[?(@.type=="kuadrant.io/RateLimitPolicyAffected")].message}'

Verification

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

    The expected outcome is an HTTP status 200 every second for 5 seconds, followed by HTTP status 429 every second for 5 seconds.

  2. 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; done

    The expected outcome is an HTTP status 200 every second for 2 seconds, followed by HTTP status 429 every second for 8 seconds.

Red Hat logoGithubredditYoutubeTwitter

Aprender

Pruebe, compre y venda

Comunidades

Acerca de Red Hat

Ofrecemos soluciones reforzadas que facilitan a las empresas trabajar en plataformas y entornos, desde el centro de datos central hasta el perímetro de la red.

Hacer que el código abierto sea más inclusivo

Red Hat se compromete a reemplazar el lenguaje problemático en nuestro código, documentación y propiedades web. Para más detalles, consulte el Blog de Red Hat.

Acerca de la documentación de Red Hat

Legal Notice

Theme

© 2026 Red Hat
Volver arriba