cachekit-rs
Production-ready caching for Rust — dual-layer L1/L2, zero-knowledge encryption, multi-backend.
Features · Quick Start · Encryption · Backends · Architecture
Overview
cachekit-rs is the Rust SDK for cachekit.io. Plug in a backend, get dual-layer caching with optional client-side encryption. Bytes never leave your process unencrypted unless you say so.
| Component | What it does |
|---|---|
| CacheKit | get / set / delete / exists with automatic L1 → L2 layering |
| SecureCache | Transparent AES-256-GCM encryption before storage (zero-knowledge) |
| Backend | Pluggable trait — cachekit.io SaaS, Redis, Cloudflare Workers |
| L1 Cache | In-process moka cache with write-through + backfill |
[!TIP] For the Python SDK with decorators, see
cachekit. For the low-level compression/encryption primitives, seecachekit-core.
Features
| Feature | Default | Description |
|---|---|---|
cachekitio |
✅ | HTTP backend for api.cachekit.io via reqwest + rustls |
encryption |
✅ | Zero-knowledge AES-256-GCM via cachekit-core |
l1 |
✅ | In-process L1 cache via moka |
redis |
❌ | Redis backend via fred (native only) |
workers |
❌ | Cloudflare Workers backend via worker |
macros |
❌ | #[cachekit] proc-macro decorator |
# Defaults: SaaS + encryption + L1
[]
= "0.2"
# With Redis backend
[]
= { = "0.2", = ["redis"] }
# For Cloudflare Workers (no L1, no Redis)
[]
= { = "0.2", = false, = ["workers", "encryption"] }
[!WARNING] Mutually exclusive features:
workers+redis— Workers runtime cannot use fredworkers+l1— moka requires std threads unavailable in wasm32
Quick Start
From Environment Variables
use *;
async
Builder API
use Arc;
use Duration;
use *;
use CachekitIO;
let backend = builder
.api_key
.build?;
let cache = builder
.backend
.default_ttl
.namespace
.l1_capacity
.build?;
[!IMPORTANT] Never hardcode API keys or master keys. Use environment variables or a secrets manager.
Zero-Knowledge Encryption
Call .secure() to get an encrypted cache handle. All values are encrypted client-side with AES-256-GCM before hitting any backend. The backend only ever sees ciphertext.
let cache = from_env?.build?;
let secure = cache.secure?;
// Encrypt → store (backend sees only ciphertext)
secure.set.await?;
// Retrieve → decrypt (transparent to caller)
let ssn: String = secure.get.await?.unwrap;
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your Code │────>│ SecureCache │────>│ Backend │
│ │ │ AES-256-GCM │ │ (cachekit.io│
│ plaintext │ │ encrypt / │ │ or Redis) │
│ │<────│ decrypt │<────│ │
└──────────────┘ └──────────────┘ └──────────────┘
L1 stores ciphertext
(zero-knowledge preserved)
| Property | Implementation |
|---|---|
| Encryption | AES-256-GCM (AEAD) via cachekit-core (ring on native, aes-gcm on wasm32) |
| Key Derivation | HKDF-SHA256 — per-tenant cryptographic isolation |
| AAD Binding | Cache key bound to ciphertext (prevents substitution attacks) |
| Memory Safety | zeroize on drop for all key material |
| L1 Guarantee | L1 stores ciphertext, never plaintext |
AAD v0x03 wire format:
[version(0x03)][len(4)][tenant_id][len(4)][cache_key][len(4)][format][len(4)][compressed]
Each field is length-prefixed with a 4-byte big-endian u32 to prevent boundary-confusion attacks. Cross-SDK compatible — ciphertext produced by the Python SDK decrypts with the Rust SDK and vice versa.
Backends
cachekit.io SaaS (default)
HTTP backend targeting api.cachekit.io with session tracking, L1 metrics headers, SSRF-safe URL validation, distributed locking, and TTL inspection.
use CachekitIO;
let backend = builder
.api_key
.api_url // optional, this is the default
.build?;
Redis
Native Redis via fred with cluster support. Requires the redis feature flag.
= { = "0.2", = ["redis"] }
use RedisBackend;
let backend = builder
.url
.build?;
backend.connect.await?; // explicit connect required
Cloudflare Workers
wasm32-unknown-unknown backend using worker::Fetch. Requires the workers feature with default features disabled.
= { = "0.2", = false, = ["workers", "encryption"] }
Implement the Backend trait to plug in any storage:
use async_trait;
use ;
use BackendError;
use Duration;
;
Optional extension traits: TtlInspectable (TTL queries), LockableBackend (distributed locking).
Dual-Layer Caching
When the l1 feature is enabled (default), CacheKit maintains an in-process moka cache in front of the backend:
┌─────────────────────────────────────────────────────────┐
│ CacheKit Client │
├─────────────────────────────────────────────────────────┤
│ │
│ GET path: │
│ L1 hit (~50ns) ──► return immediately │
│ L1 miss ──► L2 backend ──► backfill L1 (30s cap) │
│ │
│ SET path: │
│ write to L2 backend ──► write-through to L1 │
│ │
│ DELETE path: │
│ invalidate L1 first ──► delete from L2 backend │
│ │
├─────────────┬───────────────────────────────────────────┤
│ L1 (moka) │ L2 (cachekit.io / Redis / Workers) │
│ ~50ns │ ~2–50ms │
└─────────────┴───────────────────────────────────────────┘
| Behavior | Detail |
|---|---|
| Write-through | set() writes to L2 first, then L1 |
| Backfill on miss | L2 hits populate L1 with a capped 30s TTL |
| Invalidate-first | delete() evicts L1 before touching L2 |
| Encrypted L1 | SecureCache stores ciphertext in L1 (never plaintext) |
| Default capacity | 1,000 entries (configurable via .l1_capacity()) |
Environment Variables
| Variable | Required | Description |
|---|---|---|
CACHEKIT_API_KEY |
✅ | API key for cachekit.io |
CACHEKIT_API_URL |
❌ | Override API endpoint (default: https://api.cachekit.io) |
CACHEKIT_MASTER_KEY |
❌ | Hex-encoded master key (min 32 bytes) for encryption |
CACHEKIT_DEFAULT_TTL |
❌ | Default TTL in seconds (min 1, default: 300) |
[!CAUTION]
CACHEKIT_API_URLmust use HTTPS and must not point to a private IP address. Both constraints are enforced at configuration time.
Architecture
cachekit-rs/
├── crates/
│ ├── cachekit/ # Main SDK crate
│ │ └── src/
│ │ ├── lib.rs # Public API + prelude
│ │ ├── client.rs # CacheKit, SecureCache, CacheKitBuilder
│ │ ├── config.rs # CachekitConfig + from_env()
│ │ ├── encryption.rs # AES-256-GCM + AAD v0x03
│ │ ├── error.rs # CachekitError, BackendError
│ │ ├── key.rs # Blake2b-256 cache key generation
│ │ ├── metrics.rs # L1 hit-rate metrics headers
│ │ ├── session.rs # SDK session tracking
│ │ ├── url_validator.rs # SSRF-safe URL validation
│ │ ├── serializer/ # MessagePack serialization
│ │ ├── l1/ # moka-based L1 cache (feature = "l1")
│ │ └── backend/
│ │ ├── mod.rs # Backend + TtlInspectable + LockableBackend traits
│ │ ├── cachekitio.rs # cachekit.io HTTP backend
│ │ ├── cachekitio_lock.rs # Distributed locking
│ │ ├── cachekitio_ttl.rs # TTL inspection
│ │ ├── redis.rs # Redis backend (feature = "redis")
│ │ └── workers.rs # Workers backend (feature = "workers")
│ │
│ └── cachekit-macros/ # Proc-macro crate
│ └── src/lib.rs # #[cachekit] decorator
│
├── Cargo.toml # Workspace root
└── Makefile # Development commands
Development
Minimum Supported Rust Version
Rust 1.85 or later (Edition 2021).
License
MIT — see LICENSE for details.