Skip to content
Documentation menu

Docs / Reference / Security

RateLimitRule

RateLimitRule manages one rate limiting rule in a zone, in its http_ratelimit phase: the rule counts the requests its expression matches, and once a client sends more than requestsPerPeriod of them in a period, the action applies to the client's matching requests for the mitigation timeout. A Free plan allows one rate limiting rule, counted per IP address over 10 seconds, with the block action.

API version
kflare.dev/v1alpha1
Scope
Namespaced
Short name
cfratelimit
Token permission
Zone · Zone WAF · Edit

Example

Every field, with the sample's values. The live lines are the repository's sample, which applies as it is; the commented ones are the other fields, filled from other samples where one sets them. Some exclude each other, so check the rules before you uncomment several.

ratelimitrule.yaml
apiVersion: kflare.dev/v1alpha1
kind: RateLimitRule
metadata:
  name: example-ratelimitrule
  namespace: default
spec:
  zoneRef:
    name: example-zone
  expression: starts_with(http.request.uri.path, "/api/")
  description: Limit each client to 100 API requests every 10 seconds
  action: block
  response:
    content: '{"error":"rate limited, try again in 10 seconds"}'
    contentType: application/json
    statusCode: 429
  ratelimit:
    characteristics:
      - cf.colo.id
      - ip.src
    period: 10
    mitigationTimeout: 10
    requestsPerPeriod: 100
    # countingExpression: <countingExpression>
    # requestsToOrigin: true
  # enabled: true
  # priority: 1

Spec

What you set, with the limits the API server enforces.

FieldDescription
action
stringrequired

Action is what Cloudflare does with a client's matching requests once it is over the rate. Free plans can only block.

- block: blocks them, with Cloudflare's response or the rule's. - challenge: issues an interactive challenge. - js_challenge: issues a JavaScript challenge. - managed_challenge: issues the challenge Cloudflare picks for the visitor. - log: only logs them (Enterprise plans).

One of: block, challenge, js_challenge, managed_challenge, log

description
string

Description is shown with the rule in the Cloudflare dashboard.

Limits: at most 4096 characters

enabled
boolean

Enabled turns the rule on or off without deleting it.

Default: true

expression
stringrequired

Expression selects the requests the rule applies to, in Cloudflare's Rules language, for example http.request.uri.path eq "/admin". Cloudflare validates it; the fields and operators it may use depend on the zone's plan.

Limits: 1 to 4096 characters

priority
integer

Priority orders the rules kflare manages in a zone and phase: lower runs first, and rules with the same priority run in order of namespace and name. Rules created outside kflare keep their place.

Limits: format int32

ratelimit
object

Ratelimit is the rule's rate limit: what requests are counted by, over what period, how many a client may send, and for how long the action applies once the client sends more.

Rule: requestsPerPeriod is required

Rule: mitigationTimeout is required

Rule: mitigationTimeout must be 0 or at least the period

Rule: characteristics must list cf.colo.id

Rule: characteristics must list a field besides cf.colo.id

ratelimit.characteristics
[]stringrequired

Characteristics are what requests are counted by: requests that share all of them share a counter. Cloudflare counts per data center, so they list cf.colo.id, and at least one other field: ip.src counts per client IP address, the only choice on Free plans; higher plans can count by other fields, such as http.request.headers["x-api-key"].

Limits: at least 1 item; at least 1 character

ratelimit.countingExpression
string

CountingExpression counts other requests than those the rule matches, for example only the failed logins among the login requests. It defaults to the rule's expression. Free plans cannot set it.

Limits: at least 1 character

ratelimit.mitigationTimeout
integer

MitigationTimeout is how long, in seconds, the action applies once a client is over the rate. It must be at least the period, or 0 to throttle instead: apply the action only to the requests over the rate (Enterprise plans). Free plans can only use 10.

Limits: format int64

ratelimit.period
integerrequired

Period is how long, in seconds, requests are counted for. Cloudflare accepts set periods between 10 seconds and an hour, and the zone's plan narrows them: Free plans can only count for 10 seconds.

Limits: at least 0; format int64

ratelimit.requestsPerPeriod
integer

RequestsPerPeriod is how many matching requests a client can send in a period before the action applies.

Limits: at least 1 and at most 1000000; format int64

ratelimit.requestsToOrigin
boolean

RequestsToOrigin counts only the requests that reach the origin, leaving out those served from Cloudflare's cache.

response
object

Response replaces Cloudflare's response to the requests a block rule blocks.

response.content
stringrequired

Content is the response body.

Limits: 1 to 30720 characters

response.contentType
stringrequired

ContentType is the response's content type.

One of: text/html, text/plain, application/json, text/xml

response.statusCode
integerrequired

StatusCode is the response's HTTP status code.

Limits: at least 400 and at most 499; format int64

zoneRef
objectrequiredimmutable

ZoneRef references the Zone, in the same namespace, the rule belongs to. Immutable after creation.

zoneRef.name
string

Name of the referent. This field is effectively required, but due to backwards compatibility is allowed to be empty. Instances of this type with an empty value here are almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

Default: ""

Rules

Checked across fields when the resource is applied.

  • response is allowed only with action block
  • ratelimit is required

Status

What kflare reports. conditions holds the Ready condition, whose reason says why a resource isn't ready.

FieldDescription
cloudflareMetadata
object

CloudflareMetadata identifies the rule in Cloudflare.

cloudflareMetadata.ref
string

Ref is the rule's ref, which kflare derives from the resource's kind, namespace and name. kflare finds the rule it manages by its ref.

cloudflareMetadata.ruleID
string

RuleID is the rule's Cloudflare ID.

cloudflareMetadata.rulesetID
string

RulesetID is the zone's entry point ruleset for the rule's phase.

cloudflareMetadata.version
string

Version is the rule's version, which Cloudflare increments whenever the rule changes.

cloudflareMetadata.zoneID
string

ZoneID is the Cloudflare zone the rule is in.

conditions
[]object

Conditions represent the latest available observations of the rule's state.

kubectl get

The columns kubectl get ratelimitrules prints.

ColumnSource
PERIOD.spec.ratelimit.period
REQUESTS.spec.ratelimit.requestsPerPeriod
ACTION.spec.action
PRIORITY.spec.priority
RULE ID.status.cloudflareMetadata.ruleID
READY.status.conditions[?(@.type=="Ready")].status
AGE.metadata.creationTimestamp

Samples

From the repository's config/samples, comments included.

cloudflare_v1alpha1_ratelimitrule.yaml
# Generated by kflare-gen from generator/generator.yaml. DO NOT EDIT.
#
# RateLimitRule is the Schema for the ratelimitrules API.
# It manages one rate limiting rule in a zone, in its http_ratelimit phase:
# the rule counts the requests its expression matches, and once a client
# sends more than requestsPerPeriod of them in a period, the action applies
# to the client's matching requests for the mitigation timeout. A Free plan
# allows one rate limiting rule, counted per IP address over 10 seconds,
# with the block action.
apiVersion: kflare.dev/v1alpha1
kind: RateLimitRule
metadata:
  name: example-ratelimitrule
  namespace: default
spec:
  zoneRef:
    name: example-zone
  expression: starts_with(http.request.uri.path, "/api/")
  description: Limit each client to 100 API requests every 10 seconds
  action: block
  response:
    content: '{"error":"rate limited, try again in 10 seconds"}'
    contentType: application/json
    statusCode: 429
  ratelimit:
    characteristics:
    - cf.colo.id
    - ip.src
    period: 10
    mitigationTimeout: 10
    requestsPerPeriod: 100

On GitHub