wso2 / wso2/api-platform

Rate limit headers implementation doesn't match draft-ietf-httpapi-ratelimit-headers-10

Open
#688 0 comments 0 reactions 1 assignee View on GitHub

@renuka-fernando is already working on this.

Since Jan 15, 2026.

Dominant language
Go
Stars
71
Forks
111
Avg merge
1d 14h
Merged PRs (30d)
110

Description

Problem Analysis

The SetIETFHeaders method in policies/advanced-ratelimit/limiter/result.go (from gateway-controllers PR #1) claims to implement the IETF draft standard draft-ietf-httpapi-ratelimit-headers-10 but actually implements a different, legacy header format.

Current Implementation

The code currently sets the following headers with plain integer values:

  • RateLimit-Limit: Maximum requests allowed
  • RateLimit-Remaining: Remaining requests in current window
  • RateLimit-Reset: Seconds until reset (integer)
  • RateLimit-Full-Quota-Reset: Seconds until full quota available (integer)
  • RateLimit-Policy: <limit>;w=<window_in_seconds> (simple format)
Expected Behavior per draft-ietf-httpapi-ratelimit-headers-10

According to the IETF draft standard, the implementation should use:

Two primary headers using Structured Fields (SF) syntax:

  1. RateLimit-Policy: Advertises quota policies (List[SF])

    • Parameters: q (quota), w (window in seconds), qu (quota unit), pk (partition key)
    • Example: RateLimit-Policy: "default";q=100;w=10
  2. RateLimit: Conveys current service limits (List[SF])

    • Parameters: r (remaining), t (reset time), qu, pk
    • Example: RateLimit: "default";r=50;t=30

The draft does NOT define RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, or RateLimit-Full-Quota-Reset as separate headers.

Suggested Fixes

Approach 1: Update Documentation (Quick Fix)
  • Remove or update the reference to draft-ietf-httpapi-ratelimit-headers-10
  • Document that this follows a legacy/custom rate limit header format (X-RateLimit-* style)
  • Clearly state this is not compliant with the IETF draft standard
Approach 2: Implement IETF Draft-10 Standard (Full Compliance)

Refactor SetIETFHeaders to emit proper Structured Fields:

  1. Replace individual RateLimit-* headers with:

    • Single RateLimit-Policy header: "<policy_name>";q=<limit>;w=<window_seconds>
    • Single RateLimit header: "<policy_name>";r=<remaining>;t=<reset_epoch>
  2. Use Structured Fields syntax (RFC 8941) for parameter encoding

  3. Convert time values appropriately:

    • Use epoch seconds for t parameter (reset time)
    • Use window duration in seconds for w parameter
  4. Consider adding support for multiple policies if needed

Approach 3: Hybrid Approach
  • Keep existing headers for backward compatibility
  • Add new IETF-compliant headers alongside
  • Use feature flag or configuration to control which headers are emitted

Impact

  • Users: May be confused by documentation claiming IETF compliance
  • Interoperability: Clients expecting IETF draft-10 format will not parse headers correctly
  • Compliance: Claiming standard compliance when not following it could lead to integration issues

References

Requested By

@DakshithaS (from PR review)


Priority: Should be addressed before release to avoid claiming false standard compliance.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.