- Rust 66.3%
- HTML 22.5%
- Shell 9.4%
- JavaScript 1%
- Makefile 0.8%
|
Some checks failed
CI / cargo test (push) Failing after 3s
Build and Test / build (push) Failing after 25s
CI / cargo check + clippy (push) Failing after 31s
Build Linux / build-linux (linux-amd64, false, x86_64-unknown-linux-musl) (push) Failing after 32s
Build Linux / build-linux (linux-arm64, true, aarch64-unknown-linux-gnu) (push) Failing after 34s
Replace the static HERO_REDIS_BASE_PATH env var / WebState field approach with a per-request Axum middleware (base_path_middleware) that reads the X-Forwarded-Prefix header on every request and injects a BasePath extension. All handlers (login, logout, SSO, index) and the auth middleware now extract BasePath via Extension instead of reading from shared state, enabling correct reverse-proxy path handling without requiring a restart or env var. Cargo.lock updated to use published git sources for hero_proc_sdk, hero_rpc_derive and hero_rpc_openrpc, and removes stale [patch.unused] entries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .cargo | ||
| .forgejo/workflows | ||
| crates | ||
| docs | ||
| examples | ||
| rhai_examples | ||
| scripts | ||
| specs | ||
| .gitignore | ||
| AUDIT_REPORT_2025-02-28.md | ||
| buildenv.sh | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| rust-toolchain.toml | ||
Hero Redis
A high-performance, Redis-compatible server built on redb with ChaCha20-Poly1305 encryption and secret-based authentication.
Architecture
hero_redis/
├── Cargo.toml # workspace root
├── crates/
│ ├── hero_redis/ # library: core Redis protocol + server implementation
│ ├── hero_redis_sdk/ # library: RESP2 client + admin helpers
│ ├── hero_redis_server/ # binary: daemon, OpenRPC management socket, redb backend
│ ├── hero_redis_ui/ # binary: Axum+HTML admin dashboard (Unix socket only)
│ └── hero_redis_examples/ # example programs using the SDK
Ports & Sockets
| Service | Port/Socket | Description |
|---|---|---|
| Redis protocol (TCP) | 3378 |
Standard Redis wire protocol (redis-cli compatible) |
| Redis protocol (Unix) | ~/hero/var/sockets/hero_redis.sock |
Local Redis protocol |
| Management (Unix) | ~/hero/var/sockets/hero_redis_server.sock |
JSON-RPC 2.0 management interface |
| Admin UI (Unix) | ~/hero/var/sockets/hero_redis_ui.sock |
Web dashboard (via hero_proxy) |
Features
- Redis Protocol Compatible - Works with redis-cli and any Redis client library
- Secret-based Auth -
AUTH <secret>/SAUTH <secret>with per-user ACLs - Open Mode - Run without authentication (like standard Redis with no requirepass)
- Multi-Database with ACL - Per-database Read/Write/Admin permissions per user
- Persistent Storage - Data stored in redb (pure Rust embedded database)
- Encryption - All values encrypted with ChaCha20-Poly1305
- Multiple Databases - Up to 1000 databases with lazy loading
- Low Memory - ~3MB at startup, databases loaded on demand
- Auto-cleanup - Idle databases automatically closed after 5 minutes
- Unix Socket & TCP - Both connection methods supported
- Vector Search - HNSW-based similarity search with the hannoy library
- Cross-platform - Linux (x86_64, aarch64) and macOS (x86_64, aarch64)
Quick Start
Install from Binaries
Download from the Forge package registry:
mkdir -p ~/hero/bin
# Download server and UI
curl -fsSL -o ~/hero/bin/hero_redis_server \
"https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_redis/dev/hero_redis_server-linux-amd64"
curl -fsSL -o ~/hero/bin/hero_redis_ui \
"https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_redis/dev/hero_redis_ui-linux-amd64"
chmod +x ~/hero/bin/hero_redis_server ~/hero/bin/hero_redis_ui
Or install via the install script:
curl -sSL https://forge.ourworld.tf/lhumina_code/hero_redis/raw/branch/main/scripts/install.sh | bash
Add to your PATH (if not already):
export PATH="$HOME/hero/bin:$PATH"
Supported platforms: Linux x86_64 (amd64), Linux aarch64 (arm64), macOS Apple Silicon (darwin-arm64)
Build from Source
git clone https://forge.ourworld.tf/lhumina_code/hero_redis.git
cd hero_redis
make build # release build
make install # build + install to ~/hero/bin/
Start Server (Open Mode — No Auth)
The simplest way to run Hero Redis, just like standard Redis with no password:
hero_redis_server
Connect and use immediately:
redis-cli -p 3378
> SET mykey myvalue
OK
> GET mykey
"myvalue"
In open mode, databases are auto-created on first use (SELECT 1, SELECT 2, etc.).
Start Server (With Authentication)
Pass one or more --admin-secret flags to enable authentication:
hero_redis_server \
--encryption-key "your-encryption-key" \
--admin-secret "my-secret-password"
Then authenticate before executing commands:
redis-cli -p 3378
> AUTH my-secret-password
OK
> SET mykey myvalue
OK
SAUTH <secret> works identically to AUTH <secret>.
Start Server + UI (hero_proc)
make run # install + start both services via hero_proc
make rundev # debug mode (RUST_LOG=debug, --admin-secret mysecret123)
Control services:
make stop # stop all services
make restart # restart all services
make logs # server logs
make logs-ui # UI logs
make status # list running services (hero_proc list)
Authentication
Hero Redis supports two modes:
Open Mode (No Auth)
Start without --admin-secret. Any AUTH call is accepted immediately. This is the default.
hero_redis_server --data-dir ~/.hero_redis
Secret-based Auth (Recommended)
Pass --admin-secret to require authentication. Multiple secrets can be set (one per flag):
hero_redis_server \
--encryption-key "your-key" \
--admin-secret "admin-secret-1" \
--admin-secret "admin-secret-2"
Authenticate with:
AUTH <secret> # standard Redis AUTH (works with any Redis client)
SAUTH <secret> # hero_redis extension (identical behaviour)
Create per-database users:
USER.CREATESECRET alice alice-secret-123
USER.GRANT 1 alice write
Users authenticate with their own secret:
AUTH alice-secret-123
Command Line Options
hero_redis_server
| Option | Default | Description |
|---|---|---|
-d, --data-dir |
~/.hero_redis |
Database directory |
--socket |
~/hero/var/sockets/hero_redis_server.sock |
Unix socket for JSON-RPC management |
-p, --port |
3378 |
TCP port for Redis RESP2 protocol |
--encryption-key |
hero_redis_default_key |
Encryption key for DB 0 |
--admin-secret |
(none) | Admin secret (repeatable; enables auth mode) |
-v, --verbose |
false | Enable debug logging |
Auth behavior:
- No
--admin-secretset → open mode (any AUTH call accepted) - One or more
--admin-secretflags → auth required before commands
User Management
Create Users
# As server admin — create a user with a secret
USER.CREATESECRET <username> <secret>
# Example
USER.CREATESECRET alice mysecretpassword
Grant / Revoke Permissions
# Grant a user access to a specific database
USER.GRANT <db_number> <username> <read|write|admin>
# Examples
USER.GRANT 1 alice write
USER.GRANT 2 bob read
# Revoke
USER.REVOKE <db_number> <username>
USER.REVOKE 1 alice
Delete a User
USER.DELETE <username>
Permission Levels
| Level | Can Read | Can Write | Can FLUSHDB | Can USER.GRANT | Can DATABASE.CREATE |
|---|---|---|---|---|---|
| read | Yes | No | No | No | No |
| write | Yes | Yes | No | No | No |
| admin | Yes | Yes | Yes | Yes (same db) | No |
| server admin | Yes | Yes | Yes | Yes | Yes |
Admin Commands
Server Admin Commands
| Command | Description |
|---|---|
DATABASE.CREATE <encryption_key> |
Create new database, returns db number |
DATABASE.STATUS [db|all] |
Show database info |
DATABASE.PUBLIC <db> <on|off> |
Enable/disable public read-only access |
USER.CREATESECRET <username> <secret> |
Create a secret-based user |
USER.DELETE <username> |
Delete a user |
Database Admin Commands
| Command | Description |
|---|---|
USER.GRANT <db> <username> <perm> |
Grant permission (read/write/admin) |
USER.REVOKE <db> <username> |
Revoke permission |
FLUSHDB |
Clear current database |
Public Read-Only Access
# Make database 1 readable by anyone (no auth required for reads)
DATABASE.PUBLIC 1 on
# Reads work without AUTH; writes still require it
GET publickey # OK
SET key value # ERR not authenticated
Supported Redis Commands
Authentication
AUTH, SAUTH
String Commands
GET, SET, MGET, MSET, DEL, EXISTS, EXPIRE, TTL, KEYS, SCAN, INCR, INCRBY, DECR, DECRBY, APPEND, STRLEN, GETRANGE, SETNX, SETEX, GETSET, TYPE
Hash Commands
HSET, HGET, HMSET, HMGET, HGETALL, HDEL, HEXISTS, HLEN, HKEYS, HVALS, HINCRBY, HSETNX, HSCAN
List Commands
LPUSH, RPUSH, LPOP, RPOP, LRANGE, LLEN, LINDEX, LSET, LREM
Set Commands
SADD, SREM, SMEMBERS, SISMEMBER, SCARD, SPOP, SUNION, SINTER, SDIFF, SSCAN
Stream Commands
XADD, XLEN, XRANGE, XREVRANGE, XREAD, XINFO, XTRIM, XGROUP, XREADGROUP, XACK, XPENDING
Vector Commands
VECTOR.CREATE, VECTOR.ADD, VECTOR.SEARCH, VECTOR.SEARCHBYID, VECTOR.GET, VECTOR.DEL, VECTOR.BUILD, VECTOR.INFO, VECTOR.LIST, VECTOR.DROP, VECTOR.CLEAR, VECTOR.EXISTS, VECTOR.LEN
Connection Commands
PING, AUTH, SAUTH, SELECT, QUIT, COMMAND
Management Commands
COMPACT, SHUTDOWN, MEMORY USAGE, MEMORY STATS, DBSIZE, FLUSHDB, INFO, CONFIG, CLIENT
Web UI
Hero Redis includes an admin dashboard at ~/hero/var/sockets/hero_redis_ui.sock. Access it through hero_proxy or route it with a local reverse proxy.
When both services are running (make run), log in with your admin secret (or user secret).
SDK / Rust Client
[dependencies]
hero_redis_sdk = { path = "crates/hero_redis_sdk" }
use hero_redis_sdk::hero_redis_client::HeroRedisClient;
// TCP connection (auth mode)
let mut client = HeroRedisClient::new("127.0.0.1", 3378, "my-secret")?;
// Unix socket connection
let mut client = HeroRedisClient::new_unix(
"~/hero/var/sockets/hero_redis.sock",
"my-secret",
)?;
// Open mode (pass any string as secret)
let mut client = HeroRedisClient::new("127.0.0.1", 3378, "")?;
client.select(1)?;
// String operations
client.set("name", "Alice")?;
let name = client.get("name")?.unwrap();
// Hashes
client.hset("user:1", "name", "Bob")?;
let user = client.hgetall("user:1")?;
// Lists
client.rpush("queue", "job1")?;
let job = client.lpop("queue")?;
// Sets
client.sadd("tags", "rust")?;
let tags = client.smembers("tags")?;
// Admin operations
use hero_redis_sdk::hero_redis_client::AdminOperations;
let db_num = client.admin().create_database("db-encryption-key")?;
client.admin().grant_permission(db_num, "alice", Permission::Write)?;
Vector Search
Hero Redis includes HNSW-based vector similarity search using the hannoy library.
Quick Start
# Create a vector index (128 dimensions, cosine similarity)
VECTOR.CREATE embeddings 128 METRIC cosine
# Add vectors (JSON format)
VECTOR.ADD embeddings 1 [0.1, 0.2, 0.3, ...]
VECTOR.ADD embeddings 2 [0.4, 0.5, 0.6, ...]
# Build the HNSW index (required before searching)
VECTOR.BUILD embeddings
# Search for similar vectors (returns top 10)
VECTOR.SEARCH embeddings [0.1, 0.2, 0.3, ...] 10
# Search by existing vector ID
VECTOR.SEARCHBYID embeddings 1 10
High-Performance Bulk Insert
Use VECTOR.ADDBATCH with binary format — ~97x faster than individual adds:
| Method | Rate | 10K vectors |
|---|---|---|
| Individual VECTOR.ADD | ~220 vec/s | ~45 sec |
| Binary VECTOR.ADDBATCH | ~21,000 vec/s | ~0.5 sec |
Binary format (little-endian):
Header (8 bytes):
- num_vectors: u32 (4 bytes)
- dimensions: u32 (4 bytes)
Per vector:
- id: u32 (4 bytes)
- vector: f32 × dimensions
Vector Commands Reference
| Command | Description |
|---|---|
VECTOR.CREATE <index> <dims> METRIC <cosine|euclidean|manhattan> |
Create index |
VECTOR.ADD <index> <id> <json_vector> |
Add single vector |
VECTOR.ADDBATCH <index> <binary_data> |
Bulk add (binary format, ~97x faster) |
VECTOR.BUILD <index> |
Build HNSW graph (required before search) |
VECTOR.SEARCH <index> <json_vector> <k> |
Find k nearest neighbors |
VECTOR.SEARCHBYID <index> <id> <k> |
Find neighbors of existing vector |
VECTOR.GET <index> <id> |
Get vector by ID |
VECTOR.DEL <index> <id> |
Delete vector |
VECTOR.INFO <index> |
Get index statistics |
VECTOR.LEN <index> |
Get vector count |
VECTOR.LIST |
List all indexes |
VECTOR.DROP <index> |
Delete index |
VECTOR.CLEAR <index> |
Remove all vectors |
Distance Metrics
| Metric | Description | Use Case |
|---|---|---|
cosine |
Cosine similarity | Text embeddings (OpenAI, etc.) |
euclidean |
L2 distance | Image embeddings |
manhattan |
L1 distance | Sparse vectors |
Common Embedding Dimensions
| Model | Dimensions |
|---|---|
| OpenAI text-embedding-ada-002 | 1536 |
| OpenAI text-embedding-3-small | 1536 |
| Cohere embed-english-v3.0 | 1024 |
| all-MiniLM-L6-v2 | 384 |
| BGE-base-en | 768 |
See docs/ai_embeddings.md for complete documentation.
Data Storage
- Data directory:
~/.hero_redis/(configurable with--data-dir) - Database files:
db0.redb,db1.redb, ...db999.redb - DB 0 is reserved for admin metadata (secrets, ACLs, database registry)
- Each database has its own encryption key
- Values are encrypted with ChaCha20-Poly1305
Building & Publishing
Makefile Targets
make build # release build
make install # build + install to ~/hero/bin/
make installdev # debug build + install (faster iteration)
make check # cargo check (fast)
make test # cargo test --workspace
make test-integration # SDK smoke tests against a running server
make test-all # test + test-integration
make fmt # cargo fmt
make lint # cargo clippy
make run # install + start services via hero_proc
make rundev # debug mode via hero_proc
make stop # stop all services
make restart # restart all services
make logs # hero_redis_server logs
make logs-ui # hero_redis_ui logs
make status # hero_proc list
make release # bump version (PATCHLEVEL from buildenv.sh)
make ship-binary # tag + push → triggers CI build & publish
Pre-built Binaries
Pre-built binaries are published to the Forgejo package registry:
| Binary | Platforms | Description |
|---|---|---|
hero_redis_server |
linux-amd64, linux-arm64, darwin-arm64 | Redis-compatible server |
hero_redis_ui |
linux-amd64, linux-arm64, darwin-arm64 | Admin web dashboard |
CI/CD Workflows
The Forgejo workflows (.forgejo/workflows/) build and publish on tagged releases:
- build-linux.yaml: Builds for
linux-amd64andlinux-arm64(with UPX compression) - build-macos.yaml: Builds for
darwin-arm64(native macOS host)
License
Apache 2.0