Overview
Sol RPC Router implements a two-tier authentication system using Redis for persistent storage and Moka for in-memory caching. Every request (HTTP and WebSocket) requires a valid API key passed as a query parameter.Architecture
Authentication is handled by theRedisKeyStore implementation in src/keystore.rs:18-141, which provides:
- Redis Storage: API keys stored as Redis hashes under
api_key:{key} - Local Cache: 60-second TTL cache using Moka to minimize Redis round-trips
- Rate Limiting: Atomic per-key RPS limits enforced via Lua script
Key Information Structure
src/keystore.rs
owner: Client identifier for tracking and metricsactive: Boolean flag to enable/disable keys without deletionrate_limit: Maximum requests per second (0 = unlimited)
Authentication Flow
1. Query Parameter Extraction
API keys are passed via theapi-key query parameter:
src/handlers.rs
2. Key Validation
The validation process runs through three stages:3. Response Codes
Authentication failures return specific HTTP status codes:| Status Code | Scenario | Response |
|---|---|---|
401 Unauthorized | No API key provided | "Unauthorized" |
401 Unauthorized | Invalid API key | "Unauthorized" |
401 Unauthorized | Key marked inactive | "Unauthorized" |
429 Too Many Requests | Rate limit exceeded | "Rate limit exceeded" |
500 Internal Server Error | Redis connection error | "Internal Server Error" |
Redis Schema
API Key Hash
Each API key is stored as a Redis hash:owner(required): Client identifier for trackingactive(optional, defaulttrue): Enable/disable flagrate_limit(required): Maximum requests per second (0 = unlimited)
Rate Limit Counter
Rate limiting uses ephemeral counters with 1-second expiration:- Increment the counter for this key
- If counter was just created (count == 1), set 1-second TTL
- Return current count
- If count > rate_limit, reject the request
Caching Strategy
Cache Configuration
src/keystore.rs
Cache Behavior
- Positive Results: Valid keys are cached for 60 seconds
- Negative Results: Invalid keys are cached as
Noneto prevent repeated Redis lookups - Inactive Keys: Cached as
Noneafter checking theactivefield - Automatic Expiration: TTL-based eviction ensures revoked keys are checked within 60s
Caching both hits and misses significantly reduces Redis load, especially during attack scenarios where invalid keys are repeatedly presented.
WebSocket Authentication
WebSocket upgrades follow the same authentication flow (src/handlers.rs:355-387):src/handlers.rs
- Authentication happens before the WebSocket upgrade
- Failed authentication prevents the upgrade (returns HTTP error)
- Rate limits apply to WebSocket upgrade requests
- The
owneris tracked in WebSocket metrics
Managing API Keys
Use therpc-admin CLI tool to manage keys:
Create a Key
List All Keys
Inspect Key Details
Update Key Settings
Revoke a Key
Rate Limiting Details
Implementation
Rate limiting is enforced at the per-key level using Redis atomic operations:src/keystore.rs
Behavior
- Sliding Window: 1-second window with automatic reset
- Atomic Operations: Lua script ensures race-free counting
- No Limit: Setting
rate_limitto0disables rate limiting - Per-Key Isolation: Each API key has independent rate limits
Error Handling
When rate limits are exceeded:src/handlers.rs
Metrics and Monitoring
Authentication events are tracked in metrics with theowner label:
src/handlers.rs
Security Considerations
Cache Timing
Cache Timing
Invalid keys are cached for 60 seconds to prevent Redis abuse. This means:
- Revoked keys may work for up to 60 more seconds
- Consider reducing TTL if immediate revocation is critical
- Balance cache duration against Redis load
Key Logging
Key Logging
API keys are partially logged for debugging (src/handlers.rs:158):Only the first 6 characters are logged to balance security and debuggability.
Rate Limit Precision
Rate Limit Precision
Rate limits are enforced per-second with atomic counters. Under high load:
- Concurrent requests may briefly exceed the limit
- Redis RTT affects enforcement latency
- Consider setting limits 10-20% below hard thresholds
Redis Availability
Redis Availability
Redis downtime affects all authentication:
- Cached keys continue working for up to 60 seconds
- New connections fail with 500 Internal Server Error
- Consider Redis clustering for high availability
Configuration
Set the Redis URL inconfig.toml:
config.toml
Redis connection is validated at startup (src/main.rs:99-105). The router exits with code 1 if Redis is unreachable.