Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: as a user I want to use the claim in JWT token as a key in limit-count plugin. #11918

Open
vamsipatils opened this issue Jan 16, 2025 · 0 comments
Labels
enhancement New feature or request

Comments

@vamsipatils
Copy link

vamsipatils commented Jan 16, 2025

Description

I would like to enhance the limit-count plugin to support using a jwt-claim value as a key.

Problem Statement

Currently, the limit-count plugin supports only static keys like "var", "var_combination", "constant". However, many real-world scenarios require dynamic rate limiting based on contexts like specific users, tenants, or roles. This capability is particularly relevant when using JWT tokens, as they can contain such contextual information.

Importance

Adding support for JWT claims as keys in the limit-count plugin provides more flexibility in managing API usage. This feature makes it possible to enforce rate limits dynamically based on JWT content, thereby catering to various business use cases such as:

  • Per-User Rate Limiting: Controlling API access for individual users.
  • Tenant-Specific Limits: Enforcing resource usage restrictions at the tenant level.
  • Role-Based Rate Controls: Applying limits depending on user roles.
  • Claim-Based Customization: Leveraging any claim from the JWT token to implement fine-grained rate limiting.

Solution Approach

To achieve this, I propose the following enhancements:

  1. JWT Claim-Based Key Type
    A new key type, jwt_claim, will be introduced. When this key type is selected, the plugin will dynamically extract the specified claim from the JWT token using the in-house JWT library:

    local jwt = require("resty.jwt")  

    If key_type is configured as "jwt_claim", the plugin will decode the token and use the claim value as the rate-limiting key:

    if conf.key_type == "jwt_claim" then  
        local decoded_token, err = jwt:verify(nil, token)  
        key = decoded_token.payload[conf.key]  
    end  

    Here, conf.key specifies the claim field to be used for rate limiting.

  2. Optional Enhancement: Remaining Time in Error Messages
    To improve the user experience, the plugin can dynamically include the remaining reset time in the error message. If $reset_in is present in the rejected_msg configuration, it will be replaced with the actual time remaining:

    local reset_in = string.gsub(conf.rejected_msg, "%$reset_in", resetTimeInSeconds)  
    return conf.rejected_code, { error_msg = reset_in }  

    Example Output:

    {  
        "error_msg": "Too Many Requests. Please retry after 476 seconds."  
    }  

    Although the headers already provide reset time details, including it in the error message makes the information more accessible and user-friendly.

Benefits

  • Dynamic Context-Based Limits: Supports user, tenant, and role-specific rate limiting.
  • Backward Compatibility: The default behavior remains unchanged.
  • Improved User Experience: Clearer feedback through enhanced error messages.

Do you think this change is suitable for a PR?

@dosubot dosubot bot added the enhancement New feature or request label Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 📋 Backlog
Development

No branches or pull requests

1 participant