PlanPolicy Extension¶
The PlanPolicy extension provides plan-based rate limiting capabilities for Kuadrant. It enables you to define different service tiers (plans) with associated rate limits and automatically categorize authenticated users into these plans based on predicate expressions.
Overview¶
PlanPolicy enhances the existing Kuadrant AuthPolicy by adding plan identification and automatic rate limiting based on authenticated user metadata. This allows you to implement tiered service offerings where different users receive different rate limits based on their subscription plan or other attributes.
How it works¶
Integration¶
PlanPolicy works in conjunction with AuthPolicy and RateLimitPolicy:
- AuthPolicy handles authentication and stores identity metadata in secrets
- PlanPolicy evaluates predicate expressions against the authenticated identity to determine the user's plan
- The policy automatically creates rate limits for each plan tier
- Rate limiting is enforced based on the identified plan
The PlanPolicy custom resource¶
Overview¶
The PlanPolicy spec includes the following parts:
- A reference to an existing Gateway API resource (
spec.targetRef) - List of plans with predicates and limits (
spec.plans)
Each plan defines:
- Tier: A unique identifier for the plan (e.g., "gold", "silver", "bronze")
- Predicate: A CEL expression that determines if a user belongs to this plan
- Limits: Rate limiting configuration for the plan
High-level example and field definition¶
apiVersion: extensions.kuadrant.io/v1alpha1
kind: PlanPolicy
metadata:
name: my-plan-policy
spec:
# Reference to an existing networking resource to attach the policy to
# Can target Gateway or HTTPRoute resources
# Must be in the same namespace as the PlanPolicy
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute # or Gateway
name: my-route
# List of plans ordered by priority (first match wins)
plans:
- tier: gold
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "gold"
limits:
daily: 1000
weekly: 5000
- tier: silver
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "silver"
limits:
daily: 500
weekly: 2000
- tier: bronze
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "bronze"
limits:
daily: 100
weekly: 500
Using the PlanPolicy¶
Targeting a HTTPRoute networking resource¶
When a PlanPolicy targets an HTTPRoute, the policy will be enforced on all traffic flowing through that specific route.
Target an HTTPRoute by setting the spec.targetRef field of the PlanPolicy as follows:
apiVersion: extensions.kuadrant.io/v1alpha1
kind: PlanPolicy
metadata:
name: my-route-plan
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
plans:
# ... plan definitions
Targeting a Gateway networking resource¶
When a PlanPolicy targets a Gateway, the policy will be enforced on all routes attached to that gateway.
Target a Gateway by setting the spec.targetRef field of the PlanPolicy as follows:
apiVersion: extensions.kuadrant.io/v1alpha1
kind: PlanPolicy
metadata:
name: my-gateway-plan
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: my-gateway
plans:
# ... plan definitions
Plan predicates¶
Plan predicates are CEL expressions that determine which plan a user belongs to. The predicates are evaluated in order, and the first matching plan is selected.
Common predicate patterns:
# Plan based on annotation in auth secret
predicate: |
has(auth.identity) && auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "gold"
# Plan based on JWT claim
predicate: |
has(auth.identity) && auth.identity.sub == "premium-user"
# Plan based on multiple conditions
predicate: |
has(auth.identity) &&
auth.identity.metadata.annotations["secret.kuadrant.io/plan-id"] == "gold" &&
auth.identity.metadata.labels["app"] == "my-app"
Plan limits¶
Plan limits define the rate limiting configuration for each tier. You can specify:
- daily: Daily request limit
- weekly: Weekly request limit
- monthly: Monthly request limit
- yearly: Yearly request limit
- custom: Custom rate limits using RateLimitPolicy Rate format
limits:
daily: 1000
weekly: 5000
monthly: 20000
yearly: 200000
custom:
- limit: 100
window: "1h"
- limit: 10
window: "1m"
Prerequisites¶
Before using PlanPolicy, ensure you have:
- Kuadrant Operator installed and running
- Gateway API resources (Gateway and HTTPRoute) configured
- AuthPolicy configured for authentication
Examples¶
Check out the following user guide for a complete example of using PlanPolicy:
Known limitations¶
- PlanPolicies can only target HTTPRoutes/Gateways defined within the same namespace as the PlanPolicy
- Plan predicates are evaluated in order - ensure more specific plans come before general ones
- Requires authentication to be configured via AuthPolicy for plan identification