IdentityFlow.Security.RateLimiting.StackExchangeRedis
0.1.0-alpha.20260722083539
dotnet add package IdentityFlow.Security.RateLimiting.StackExchangeRedis --version 0.1.0-alpha.20260722083539
NuGet\Install-Package IdentityFlow.Security.RateLimiting.StackExchangeRedis -Version 0.1.0-alpha.20260722083539
<PackageReference Include="IdentityFlow.Security.RateLimiting.StackExchangeRedis" Version="0.1.0-alpha.20260722083539" />
<PackageVersion Include="IdentityFlow.Security.RateLimiting.StackExchangeRedis" Version="0.1.0-alpha.20260722083539" />
<PackageReference Include="IdentityFlow.Security.RateLimiting.StackExchangeRedis" />
paket add IdentityFlow.Security.RateLimiting.StackExchangeRedis --version 0.1.0-alpha.20260722083539
#r "nuget: IdentityFlow.Security.RateLimiting.StackExchangeRedis, 0.1.0-alpha.20260722083539"
#:package IdentityFlow.Security.RateLimiting.StackExchangeRedis@0.1.0-alpha.20260722083539
#addin nuget:?package=IdentityFlow.Security.RateLimiting.StackExchangeRedis&version=0.1.0-alpha.20260722083539&prerelease
#tool nuget:?package=IdentityFlow.Security.RateLimiting.StackExchangeRedis&version=0.1.0-alpha.20260722083539&prerelease
IdentityFlow.Security.RateLimiting.StackExchangeRedis
Atomic Redis-backed rate limiting for IdentityFlow.
services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect("localhost:6379"));
services.AddIdentityFlowStackExchangeRedisRateLimiting(
options => options.Policies["sign_in"] = new(5, TimeSpan.FromMinutes(15)),
redis =>
{
redis.EnableManagementStore = true;
redis.EnableManagementIndexes = true;
redis.BucketHashKey = Convert.FromBase64String(
configuration["IdentityFlow:RedisBucketHashKey"]!); // exactly 32 bytes
});
Raw partition keys are never stored in Redis or returned by management APIs. When management or
indexes are enabled, BucketHashKey is required and must be the same 32-byte secret on every
instance sharing the Redis key prefix. Bucket identifiers are HMAC-SHA-256 values derived from the
policy name and partition key. Load this key from secret storage; do not hard-code it or reuse it for
another purpose.
By default, management search/reset uses Redis key scanning. Leave EnableManagementStore
disabled when the Redis server policy does not permit SCAN. Management prefixes must be non-empty
after normalization and cannot contain Redis glob metacharacters. Indexed prefixes also cannot
contain Redis hash-tag braces.
Set EnableManagementIndexes = true to maintain bounded-expiry, stable-sort, and bucket-hash
indexes. Exceeded state and policy limits are derived from the live counter and one current policy
snapshot for each management operation, so limit changes take effect without another consume.
Indexed management queries read buckets incrementally. Enabling indexes does not backfill existing
untagged counters; those counters expire by TTL while new indexed counters use the indexed layout.
TotalCount, when requested, is the exact number of live buckets matching the non-page filters at
the time of that search. It is independent of cursor position and page limit. The count is null
when IncludeTotalCount = false; use that mode when a count is not needed because counted pages
must walk every matching bucket. Separate calls are not a distributed snapshot, so concurrent
consume/reset/expiry activity can legitimately change the count between pages.
Uncounted indexed searches stop after a bounded candidate budget when a sparse filter (for example,
Exceeded = true) cannot fill the page. Narrow the policy/bucket filter or explicitly request a
total count when an intentional full index walk is acceptable.
Non-indexed scan fallback has bounded SCAN-command and matching-key budgets and should be treated as an operational fallback, not the preferred production management path. Non-indexed reset issues bounded single-key deletes so untagged counters remain valid on Redis Cluster.
Failure-only authentication throttles use failure-lease:v1 state so active valid requests can
hold provisional capacity without incrementing or later decrementing a failure counter. That state
is the authoritative enforcement source for those flows and is intentionally separate from v2
counters: mirroring a commit with a second Redis command would create a non-atomic, misleading
counter. The current management search/reset adapter covers v2 counters and indexes only; it does
not display or reset active/committed failure leases. Lease state expires automatically within its
policy window (Redis failure-lease policies support windows up to 30 days).
Indexed mode deliberately wraps the effective prefix in one Redis Cluster hash tag. This keeps the counter and all index updates atomic in Lua, but pins all rate-limit keys for that prefix to one cluster slot and therefore one shard. Use distinct prefixes to distribute independent deployments, or leave indexes disabled when cross-shard counter distribution is more important than indexed management.
Management pressure is independently bounded with ManagementReadBatchSize (default 64),
ManagementResetConcurrency (default 8), and ManagementPruneBatchSize (default 128).
Keep these conservative: larger values reduce client-side waits but queue more commands and script
keys at Redis. The read batch also caps stale-index cleanup commands per dispatch. Management
activities expose logical Redis command, bounded-dispatch, and elapsed-time tags.
Key and index migration
This package currently writes v2 counter keys and idx:v2 indexes. Earlier layouts are not read
or mutated; their TTLs provide cleanup. The v2 transition and any BucketHashKey change therefore
start new enforcing counters. Never roll a shared Redis deployment with different hash keys active
at the same time, because nodes would enforce and index different buckets for the same subject.
Coordinate key rotation across all instances (preferably with a new KeyPrefix) and allow the old
prefix to age out for at least the maximum policy window before deleting it.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- IdentityFlow.Security.RateLimiting (>= 0.1.0-alpha.20260722083539)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- StackExchange.Redis (>= 3.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-alpha.20260722083539 | 29 | 7/22/2026 |
| 0.1.0-alpha.20260722073217 | 31 | 7/22/2026 |
| 0.1.0-alpha.20260620175120 | 63 | 6/20/2026 |
| 0.1.0-alpha.20260620172859 | 59 | 6/20/2026 |
| 0.1.0-alpha.20260620170646 | 62 | 6/20/2026 |
| 0.1.0-alpha.20260620143000 | 59 | 6/20/2026 |
| 0.1.0-alpha.20260620135000 | 56 | 6/20/2026 |
| 0.1.0-alpha.20260620122408 | 58 | 6/20/2026 |
| 0.1.0-alpha.20260614215234 | 57 | 6/14/2026 |