Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _topic_maps/_topic_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Topics:
File: rhcl-using-x509-crypt-id-verify
- Name: Using OpenID Connect authentication
File: rhcl-oidc-authentication
- Name: Configure and deploy a PlanPolicy
File: rhcl-planpolicy
---
Name: Registering MCP servers and creating policies
Dir: mcp_gateway_config
Expand Down
40 changes: 40 additions & 0 deletions deployment/rhcl-planpolicy.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:_mod-docs-content-type: ASSEMBLY
include::_attributes/attributes.adoc[]
[id="rhcl-planpolicy"]
= Configure and deploy the PlanPolicy extension
:context: rhcl-planpolicy

toc::[]

[role="_abstract"]
With a `PlanPolicy` extension, you can define different service tiers, or plans, with their associated rate limits and automatically categorize authenticated users into these plans.

include::modules/con-rhcl-planpolicy-overview.adoc[leveloffset=+1]

include::modules/proc-rhcl-configuring-authentication-planpolicy.adoc[leveloffset=+2]

include::modules/proc-rhcl-authpolicy-verify.adoc[leveloffset=+2]

include::modules/proc-rhcl-create-secrets.adoc[leveloffset=+2]

include::modules/proc-rhcl-secrets-verify.adoc[leveloffset=+2]

include::modules/proc-rhcl-deploying-planpolicy-rate-limiting.adoc[leveloffset=+2]

//include::modules/proc-rhcl-planpolicy-ratelimiting-verify.adoc[leveloffset=+2]

include::modules/ref-rhcl-planpolicy-custom-resources-params.adoc[leveloffset=+1]

include::modules/ref-rhcl-planpolicy-targeting-routes.adoc[leveloffset=+2]

include::modules/ref-rhcl-planpolicy-target-gateway.adoc[leveloffset=+2]

include::modules/ref-rhcl-planpolicy-plan-predicates.adoc[leveloffset=+2]

include::modules/ref-rhcl-planpolicy-plan-limits.adoc[leveloffset=+2]

include::modules/ref-rhcl-planpolicy-known-limitations.adoc[leveloffset=+2]

== Additional resources

* link:rhcl-ocp-web-console[Using the {product-title} web console]
21 changes: 21 additions & 0 deletions modules/con-rhcl-planpolicy-overview.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Module included in the following assemblies:
//
// *deployment/rhcl-planpolicy.adoc

:_mod-docs-content-type: CONCEPT
[id="con-rhcl-planpolicy-overview_{context}"]
= PlanPolicy

[role="_abstract"]
You can use a `PlanPolicy` object to implement tiered service offerings where different users receive different rate limits based on their subscription plan or other attributes.

[NOTE]
====
The `PlanPolicy` object uses the `spec.plans.limits` parameter to enforce rate limits at the plan tier level instead of the individual subscriber level.
====

A `PlanPolicy` works in conjunction with `AuthPolicy` and `RateLimitPolicy` custom resources (CRs) in the following sequence:

. An `AuthPolicy` CR authenticates a user request with stored identity metadata, including their plan information.
. The `PlanPolicy` object evaluates CEL predicate expressions against the authenticated identity to determine the user's plan tier.
. {prodname} then enforces the rate limits defined for the user-matched plan tier.
60 changes: 60 additions & 0 deletions modules/proc-rhcl-authpolicy-verify.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Module included in the following assemblies:
//
// *deployment/rhcl-planpolicy.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-rhcl-authpolicy-verify_{context}"]
= Verifying the acceptance of the 'AuthPolicy' CR

[role="_abstract"]
You can confirm the acceptance of the `AuthPolicy` custom resource (CR) by running several commands.

.Procedure

. Confirm that the `AuthPolicy` CR was accepted by checking its status by running the following command:
+
[source,terminal,subs="+quotes"]
----
$ oc get authpolicy _<sample_app>_ -n ${KUADRANT_GATEWAY_NS} -o jsonpath='{.status.conditions}'
----
* Replace `_<sample_app>_` with the name of your application.
* Replace ${KUADRANT_GATEWAY_NS} with the namespace you used for this {prodname} deployment.
+
.Expected output
[source,terminal,subs="+quotes"]
----
AuthPolicy has been accepted
AuthPolicy has been successfully enforced
----
+
. Send a request using the bronze-tier API key and confirm that it succeeds by running the following command:
+
[source,terminal,subs="+quotes"]
----
$ curl -H 'Authorization: APIKEY _<bronze_api_key_value>_' http://${KUADRANT_GATEWAY_HOSTNAME}/toy -i
----
* Replace `_<bronze_api_key_value>_` with the actual API key string you want to assign to each tier.
* KUADRANT_GATEWAY_HOSTNAME: Hostname of your gateway in {prodname}.
+
.Expected output
[source,terminal,subs="+quotes"]
----
HTTP/1.1 200 OK
----
+
. Send a second request using the bronze-tier key and confirm that it is rate limited by running the following command:
+
[source,terminal,subs="+quotes"]
----
$ curl -H 'Authorization: APIKEY _<bronze-api-key-value>_' http://${KUADRANT_GATEWAY_HOSTNAME}/toy -i
----
* Replace `_<bronze_api_key_value>_` with the actual API key string you want to assign to each tier.
* KUADRANT_GATEWAY_HOSTNAME is the host name of your gateway in {prodname}.
+
.Expected output
[source,terminal,subs="+quotes"]
----
HTTP/1.1 429 Too Many Requests
----
+
. Confirm that the gold-tier key allows up to five requests per day before the limit is enforced.
60 changes: 60 additions & 0 deletions modules/proc-rhcl-configuring-authentication-planpolicy.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Module included in the following assemblies:
//
// *deployment/rhcl-planpolicy.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-rhcl-configuring-authentication-planpolicy_{context}"]
= Creating an AuthPolicy with API key authentication

[role="_abstract"]
You can configure API key authentication on a Gateway by deploying an AuthPolicy and creating per-plan API key secrets, so that {prodname} can identify which rate-limiting plan applies to each request.

.Prerequisites

* You installed {prodname}.
* You installed {oc-first}.
* You are logged in to your cluster.
* You created the `Gateway` object for your deployment.

.Procedure

. Deploy an AuthPolicy that targets the Gateway and enables API key authentication by using the following example:
+
.Example API key AuthPolicy CR
[source,yaml,subs="+quotes"]
----
apiVersion: kuadrant.io/v1
kind: AuthPolicy
metadata:
name: _<sample_app>_
namespace: ${KUADRANT_GATEWAY_NS}
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: ${KUADRANT_GATEWAY_NAME}
rules:
authentication:
"api-key-plan":
apiKey:
selector:
matchLabels:
app: _<sample_app>_
allNamespaces: true
credentials:
authorizationHeader:
prefix: APIKEYapiVersion: kuadrant.io/v1
----
* Replace `_<sample_app>_ ` with the name of your application.
* Replace 'KUADRANT_GATEWAY_NS' with the namespace for your gateway in {prodname}.
* Replace `KUADRANT_GATEWAY_NAME` with the name of your gateway in {prodname}.
+
* The `spec.rules.authentication."api-key-plan".apiKey.selector.matchLabels` field value points to the API key `Secrets` objects that carry the `app: _<sample_app>_` label.
* Setting `spec.rules.rules.authentication."api-key-plan".apiKey.selector.allNamespaces: true` allows secrets from any namespace to be matched.
+
. Apply the policy by running the following command:
+
[source,terminal,subs="+quotes"]
----
$ oc apply -f
----
67 changes: 67 additions & 0 deletions modules/proc-rhcl-create-secrets.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Module included in the following assemblies:
//
// *deployment/rhcl-planpolicy.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-rhcl-create-secrets_{context}"]
= Creating API key `Secret` objects

[role="_abstract"]
You can create API key 'Secret` objects for each plan tier.

[IMPORTANT]
====
The following example creates API key `Secret` objects each plan tier that you want to use. 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.
====

.Procedure
. Create API key `Secret` objects for each plan tier that you want to use. Each `Secret` must carry the `authorino.kuadrant.io/managed-by: authorino` label and a `secret.kuadrant.io/plan-id` annotation that identifies the plan tier as shown in the following example:
+
.Example `Secret` object for plan tiers
[source,yaml,subs="+quotes"]
----
apiVersion: v1
kind: Secret
metadata:
name: gold-key
namespace: ${KUADRANT_DEVELOPER_NS}
labels:
authorino.kuadrant.io/managed-by: authorino
app: _<sample_app.yaml>_
annotations:
secret.kuadrant.io/plan-id: gold
stringData:
api_key: _<gold_api_key_value>_
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:curl
name: silver-key
namespace: ${KUADRANT_GATEWAY_NS}
labels:
authorino.kuadrant.io/managed-by: authorino
app: _<sample_app.yaml>_
annotations:
secret.kuadrant.io/plan-id: silver
stringData:
api_key: _<silver_api_key_value>_
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
name: bronze-key
namespace: ${KUADRANT_GATEWAY_NS}
labels:
authorino.kuadrant.io/managed-by: authorino
app: _<sample_app>_
annotations:
secret.kuadrant.io/plan-id: bronze
stringData:
api_key: _<bronze_api_key_value>_
type: Opaque
----
* Replace 'KUADRANT_GATEWAY_NS' with the namespace for the object.
* Replace `_<sample_app.yaml>_ ` with the name of your application.
* Replace `_<gold_api_key_value>_`, `_<silver_api_key_value>_`, and `_<bronze_api_key_value>_` with the actual API key strings you want to assign to each tier.
91 changes: 91 additions & 0 deletions modules/proc-rhcl-deploying-planpolicy-rate-limiting.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Module included in the following assemblies:
//
// *deployment/rhcl-planpolicy.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-rhcl-deploying-planpolicy-rate-limiting_{context}"]
= Deploying plan-based rate limiting with a PlanPolicy

[role="_abstract"]
After you create your `AuthPolicy` and secrets, you can create a `PlanPolicy` object to enforce tiered rate limits on specific authenticated users.

[NOTE]
====
You can create a `PlanPolicy` object by using the {prodname} web console plugin.
====

.Prerequisites

* You installed {prodname}
* You installed {oc-first}.
* You are logged in to your cluster.
* You created the `Gateway` object for your deployment.
* You configured API key-based authentication.

[NOTE]
====
A `PlanPolicy` can target and HTTPRoute, Gateway, or GRPCRoute.
====

.Procedure

. Create a `PlanPolicy` object to enforce plan-based rate limits on the gateway by using the following example.
+
.Example PlanPolicy object
[source,yaml,subs="+quotes"]
----
apiVersion: extensions.kuadrant.io/v1alpha1
kind: PlanPolicy
metadata:
name: <sample_app_planpolicy.yaml>
namespace: ${KUADRANT_DEVELOPER_NS}
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: _<sample_app.yaml>_
plans:
- tier: gold
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "gold"
limits:
daily: 5
- tier: silver
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "silver"
limits:
daily: 2
- tier: bronze
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "bronze"
limits:
daily: 1
----
+
[NOTE]
====
The `PlanPolicy` object uses the `spec.plans.limits` parameter to enforce rate limits at the plan tier level instead of the individual subscriber level.
====
+
* Replace `_<sample_app.yaml>_` with the name of your application.
* Replace `_<sample_app_planpolicy.yaml>_ with the `PlanPolicy` object for your application.
* Replace 'KUADRANT_DEVELOPER_NS' with the namespace for your developer in {prodname}.
* Each `predicate` is a CEL expression. The predicates are evaluated in order, and the first matching plan is applied to the authenticated user.
+
[NOTE]
====
The CEL expressions can be anything that applies to your use case. You can use an expression different from the `secret.kuadrant.io/plan-id` expression.
====
+
* The `limits` field supports the following windows: `daily`, `weekly`, `monthly`, `yearly`, and `custom`. Custom limits take a `limit` value and a `window` duration string, for example:
+
[source,yaml]
----
limits:
daily: 100
weekly: 500
monthly: 2000
custom:
- limit: 10
window: "1m"
----
Loading