Skip to content

Redis Key Patterns

All Redis keys are prefixed with config.redisPrefix (default: guard_core:). Key patterns are cross-language compatible with the Python guard-core library.

HandlerKey PatternValue TypeTTL
RateLimitManager{prefix}rate_limit:rate:{ip}:{endpoint}Sorted set (timestamps)window * 2
IPBanManager{prefix}banned_ips:{ip}String (expiry timestamp)Ban duration
CloudHandler{prefix}cloud_ranges:{provider}String (comma-separated CIDRs)cloudIpRefreshInterval
SusPatternsManager{prefix}patterns:customString (comma-separated patterns)None
SecurityHeadersManager{prefix}security_headers:csp_configJSON string86400s
SecurityHeadersManager{prefix}security_headers:hsts_configJSON string86400s
SecurityHeadersManager{prefix}security_headers:custom_headersJSON string86400s
BehaviorTracker{prefix}behavior:usage:{endpoint}:{client_ip}Key-valueRule window
BehaviorTracker{prefix}behavior:return:{endpoint}:{client_ip}:{pattern}Key-valueRule window
IPInfoManager{prefix}ipinfo:databaseString (latin-1 encoded DB)86400s

With the default prefix guard_core::

guard_core:rate_limit:rate:192.168.1.1:/api/login
guard_core:banned_ips:10.0.0.50
guard_core:cloud_ranges:AWS
guard_core:cloud_ranges:GCP
guard_core:cloud_ranges:Azure
guard_core:patterns:custom
guard_core:security_headers:csp_config
guard_core:security_headers:hsts_config
guard_core:security_headers:custom_headers
guard_core:behavior:usage:/api/redeem:192.168.1.1
guard_core:behavior:return:/api/redeem:192.168.1.1:status:404

The rate limit check uses an atomic Lua script loaded via SCRIPT LOAD and executed with EVALSHA:

local key = KEYS[1]
local now = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local limit = tonumber(ARGV[3])
local window_start = now - window
redis.call('ZADD', key, now, now)
redis.call('ZREMRANGEBYSCORE', key, 0, window_start)
local count = redis.call('ZCARD', key)
redis.call('EXPIRE', key, window * 2)
return count

How it works:

  1. ZADD adds the current timestamp as both score and member
  2. ZREMRANGEBYSCORE removes all entries older than the window
  3. ZCARD returns the count of entries in the window
  4. EXPIRE sets the key TTL to window * 2 for cleanup

The script is executed in a single Redis transaction, preventing race conditions in concurrent environments.

Fallback: If EVALSHA fails (script not cached), the manager falls back to individual ZADD, ZREMRANGEBYSCORE, ZCARD, and EXPIRE commands. If Redis is entirely unavailable, it falls back to in-memory tracking.

The RedisManager formats keys as:

{prefix}{namespace}:{key}

Where prefix is config.redisPrefix (default guard_core:), namespace is the handler’s domain (e.g., banned_ips, rate_limit), and key is the specific identifier.

These key patterns are identical to the Python guard-core library. A TypeScript deployment and a Python deployment sharing the same Redis instance will see each other’s bans, rate limits, cloud ranges, and custom patterns.

To enable this, both deployments must use the same redisPrefix value.

Keys with TTL expire automatically. Keys without TTL (patterns:custom) persist until explicitly deleted via reset() or removePattern().

To clear all guard keys from Redis:

Terminal window
redis-cli KEYS "guard_core:*" | xargs redis-cli DEL