Repository navigation
feat(core): standalone checkRateLimitByIp primitive (matrix gap 12) - #112
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
rennf93
force-pushed
the
feat/check-rate-limit-by-ip
branch
2 times, most recently
from
October 7, 2026 18:46
ecb6876 to
d605a06
Compare
The full request-free rate-limit subsystem ported from
check_rate_limit_by_ip (handlers/ratelimit_handler.py): dedicated
LRU-capped sliding-window counters, the sha256 _hash_identity_segment
endpoint suffix (raw path text never reaches Redis), fail-open/fail-closed
Redis resolution with GuardRedisError and the once-per-process in-memory
fallback warning, and the dedicated auto-ban feed resolved through the same
pure threshold helper the middleware path uses (threatBanConfig rate_limit
first, then the flat threshold; passive-mode suppression; no counting and no
re-ban once the ip is already banned; reason rate_limit_exceeded).
Input validation runs before any side effect: a rejected ip or an endpoint
path containing ':' records no hit and feeds no ban, with the rejection
message redacted. The default empty endpoint path shares the pipeline's
global bucket by design. Exported from the package root like the reference
guard_core.utils surface.
Also fixes the redaction module's URL splitter: a scheme without //
('a:password=x') now parses as scheme + path (the urlsplit semantics the
reference redactor relies on), and the path itself gets the pair redaction
pass (_redact_sensitive_path twin).
rennf93
force-pushed
the
feat/check-rate-limit-by-ip
branch
from
October 7, 2026 19:04
d605a06 to
73df43a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes matrix gap 12 (A8 check_rate_limit_by_ip) - the TRAILING flag comes off. The full subsystem is ported, not a wrapper over the tiered check:
handlers/rate-limit-by-ip.ts: the dedicated LRU-capped sliding-window stores (byIpRequestTimestamps,byIpAutobanCountsexported like the reference module globals, evict-oldest with touch-refresh), the_lru_pop_or_createtwin,_hash_identity_segment(sha256 hex endpoint suffix so raw path text never reaches Redis and distinct budgets cannot collide), the_redis_request_counttwin (sha-less pipeline path: zadd/zremrangebyscore/zcard/expire), the_resolve_redis_rate_limit_failuretwin (fail-closed raisesGuardRedisError(503, 'Redis rate limiting unavailable'); fail-open warns once and falls back to the in-memory window), and_feed_rate_limit_autoban(dedicated counter, never merged with the pipeline's suspicious counts; resolved through the same pureresolveThresholdBanhelper the middleware path uses; passive-mode suppression; already-banned short-circuit before the counter increments;rate_limit_exceededreason; threatBanConfig rate_limit first, then the flat threshold).:records no hit and feeds no ban; the rejection message redacts the path. To make the reference redaction contract real, the URL splitter now parses scheme-without-//inputs as scheme + path (theurlsplitsemantics) and the path gets the pair-redaction pass (_redact_sensitive_pathtwin) -redactEndpointForDisplay('a:password=x')now answersa:password=[REDACTED]like the reference.guard_core.utilssurface.Matrix rows flipped
Tests
38 tests in tests/test-handlers/rate-limit-by-ip.test.ts mirroring tests/test_core/test_check_rate_limit_by_ip.py and test_check_rate_limit_by_ip_autoban.py (live-Redis window enforcement, bidirectional bucket sharing, hashed-key isolation, redacted rejection message, LRU eviction arms, all autoban knob arms, counter isolation from the middleware, eviction arms).
Gates
Stacked on #111 (#109 -> #110 -> #111 -> this); merge in order.