No description
  • Rust 78.7%
  • HTML 21.3%
Find a file
despiegk 3ca1befa5d
All checks were successful
Build and Test / build (push) Successful in 5m24s
lab publish / publish (push) Successful in 7m7s
refactor: migrate hero_db_server and hero_db_admin to hero_lifecycle
Replace manual Unix socket / signal / banner boilerplate in both daemons
with the `hero_rpc_server!` and `hero_admin_server!` macros from
`hero_lifecycle`. Server startup, SIGTERM/SIGINT handling, socket bind,
and `--info` / SERVICE_TOML plumbing are now owned by the lifecycle crate.

- Add `hero_lifecycle` workspace dependency (hero_blueprint dev branch)
- `hero_db_server`: drop `service_base!`, `CancellationToken`, manual
  signal loop, `run()`; inline the server setup and delegate serving to
  `rpc_server.serve(build_user_router(state))`
- `hero_db_server`: add `build_user_router()` (user routes only, no
  mandatory endpoints — lifecycle injects those via `serve()`)
- `hero_db_admin`: drop `service_base!`, manual Unix listener, signal
  loop, `run_serve()`; delegate to `admin_server.serve(app)`
- Drop `Cargo.toml.hero_builder_backup`
- Update Cargo.lock (hero_lifecycle added; hyper 1.10, http 1.4.1,
  herolib_core, hero_rpc2/hero_rpc_derive consolidated to blueprint)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 22:32:03 +02:00
.cargo feat: rename hero_redis to hero_db across entire codebase 2026-04-04 11:15:44 +02:00
.forgejo/workflows ci: install lab onto PATH from ~/.local/bin in the publish workflow 2026-05-29 15:42:19 -04:00
.hero refactor: remove custom session auth from hero_db_admin, fetch theme from hero_proc 2026-05-10 23:05:32 +02:00
crates refactor: migrate hero_db_server and hero_db_admin to hero_lifecycle 2026-05-29 22:32:03 +02:00
docs refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
rhai_examples feat: rename hero_redis to hero_db across entire codebase 2026-04-04 11:15:44 +02:00
specs refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
.gitignore refactor: port hero_redis to Hero Service architecture 2026-02-24 16:02:44 +02:00
AUDIT_REPORT_2025-02-28.md refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
Cargo.lock refactor: migrate hero_db_server and hero_db_admin to hero_lifecycle 2026-05-29 22:32:03 +02:00
Cargo.toml refactor: migrate hero_db_server and hero_db_admin to hero_lifecycle 2026-05-29 22:32:03 +02:00
CLAUDE.md refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
LICENSE Hero Redis: optimized Redis server on redb 2025-12-25 10:08:48 +01:00
PURPOSE.md refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
README.md feat: add graph purge-by-prop commands, ontology.create RPC, and admin RPC proxy 2026-05-29 20:43:02 +02:00
rust-toolchain.toml chore: bump rust toolchain to 1.95 2026-05-08 16:25:51 +02:00

Hero Redis

A high-performance, Redis-compatible server with ChaCha20-Poly1305 encryption and secret-based authentication.

Architecture

hero_db/
├── Cargo.toml # workspace root
├── crates/
│ ├── hero_db/ # library: core Redis protocol + server implementation
│ ├── hero_db_sdk/ # library: RESP2 client + admin helpers
│ ├── hero_db_server/ # binary: daemon, OpenRPC management socket, database backend
│ ├── hero_db_admin/ # binary: Axum+HTML admin dashboard (Unix socket only)
│ └── hero_db_examples/ # example programs using the SDK

Ports & Sockets

Socket / Port Protocol Description
$PATH_SOCKET/hero_db/rpc.sock HTTP/1.1 OpenRPC JSON-RPC 2.0 management API
$PATH_SOCKET/hero_db/resp.sock RESP2 Redis wire protocol (redis-cli / SDK via Unix)
TCP 0.0.0.0:6378 RESP2 Redis wire protocol (redis-cli / SDK via TCP)
$PATH_SOCKET/hero_db/admin.sock HTTP/1.1 Admin web dashboard (via hero_router)

PATH_SOCKET defaults to ~/hero/var/sockets.

Each socket serves exactly one protocol — no multiplexing.

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 the database engine
  • 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 admin
curl -fsSL -o ~/hero/bin/hero_db_server \
 "https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_db/dev/hero_db_server-x86_64-unknown-linux-musl"
curl -fsSL -o ~/hero/bin/hero_db_admin \
 "https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_db/dev/hero_db_admin-x86_64-unknown-linux-musl"
chmod +x ~/hero/bin/hero_db_server ~/hero/bin/hero_db_admin

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_db.git
cd hero_db
lab build # release build
lab service db --install # install all binaries to ~/hero/bin/

Start Server (Open Mode — No Auth)

The simplest way to run Hero Redis, just like standard Redis with no password:

hero_db_server

Connect and use immediately:

redis-cli -p 6378
> 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_db_server \
 --encryption-key "your-encryption-key" \
 --admin-secret "my-secret-password"

Then authenticate before executing commands:

redis-cli -p 6378
> AUTH my-secret-password
OK
> SET mykey myvalue
OK

SAUTH <secret> works identically to AUTH <secret>.

Start Server + UI (via lab / hero_proc)

lab service db --install # build + install all binaries
lab service db --start # register with hero_proc and start server + admin
lab service db --stop # stop all components
lab service db --status # show running status

Testing with redis-cli

Once the server is running (lab service db --start), connect via TCP:

redis-cli -p 6378

Basic smoke test:

# Connection
redis-cli -p 6378 PING
# → PONG

# String
redis-cli -p 6378 SET mykey "hello from hero_db"
redis-cli -p 6378 GET mykey
# → hello from hero_db

# Hash
redis-cli -p 6378 HSET user:1 name Alice age 30
redis-cli -p 6378 HGETALL user:1
# → name Alice age 30

# List
redis-cli -p 6378 RPUSH mylist a b c
redis-cli -p 6378 LRANGE mylist 0 -1
# → a b c

# Server info
redis-cli -p 6378 DBSIZE
redis-cli -p 6378 INFO server

Or test via the Unix socket directly (bypasses TCP, useful for local scripts):

redis-cli -s ~/hero/var/sockets/hero_db/resp.sock PING
# → PONG

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_db_server --data-dir ~/.hero_db

Pass --admin-secret to require authentication. Multiple secrets can be set (one per flag):

hero_db_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_db 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_db_server

Option / Env Var Default Description
HERO_DB_DATA_DIR ~/.hero_db Database directory
HERO_DB_SERVER_SOCKET $PATH_SOCKET/hero_db/rpc.sock Unix socket for JSON-RPC management
HERO_DB_PORT 6378 TCP port for Redis RESP2 protocol
HERO_DB_ENCRYPTION_KEY hero_db_default_key Encryption key for DB 0
REDIS_ADMIN_SECRET (none) Admin secret (enables auth mode)
RUST_LOG info Log level (debug, trace, etc.)

Auth behavior:

  • No --admin-secret set → open mode (any AUTH call accepted)
  • One or more --admin-secret flags → 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

Admin UI

Hero Redis includes an admin dashboard at $PATH_SOCKET/hero_db/admin.sock. Access it through hero_router at http://localhost:9988/hero_db/ui/.

When both services are running (lab service db --start), log in with your admin secret (or user secret).

SDK / Rust Client

[dependencies]
hero_db_sdk = { path = "crates/hero_db_sdk" }
use hero_db_sdk::hero_db_client::HeroDbClient;

// TCP connection (auth mode)
let mut client = HeroDbClient::new("127.0.0.1", 6378, "my-secret")?;

// Unix socket connection
let mut client = HeroDbClient::new_unix(
 "~/hero/var/sockets/hero_db/resp.sock",
 "my-secret",
)?;

// Open mode (pass any string as secret)
let mut client = HeroDbClient::new("127.0.0.1", 6378, "")?;

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_db_sdk::hero_db_client::AdminOperations;
let db_num = client.admin().create_database("db-encryption-key")?;
client.admin().grant_permission(db_num, "alice", Permission::Write)?;

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

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.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.

Graph

Hero Redis includes a built-in property graph engine supporting nodes and edges with arbitrary JSON properties, multi-hop traversal, shortest-path queries, and statistics. Graphs are stored per-database alongside regular key/value data.

Graph Commands Reference

Command Description
graph.node.add <id> <props_json> Add a node with properties
graph.node.get <id> Get a node by ID
graph.node.set <id> <props_json> Update node properties
graph.node.del <id> Delete a node
graph.node.find <filter_json> Find nodes matching a property filter
graph.node.count Count all nodes
graph.edge.add <src> <dst> <label> <props_json> Add a directed edge
graph.edge.get <src> <dst> <label> Get an edge
graph.edge.del <src> <dst> <label> Delete an edge
graph.edge.find <filter_json> Find edges matching a property filter
graph.edge.count Count all edges
graph.neighbors <id> List neighbors of a node
graph.traverse <start_id> <depth> Traverse the graph from a node up to a given depth
graph.path <src_id> <dst_id> Find shortest path between two nodes
graph.stats Return node/edge counts and graph statistics
graph.clear Remove all nodes and edges

Data Storage

  • Data directory: ~/.hero_db/ (configurable with --data-dir)
  • Database files: db0.db, db1.db, ... db999.db
  • 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

Lab Commands

lab build # release build
lab service db --install # build + install all binaries to ~/hero/bin/
cargo check # fast syntax check
cargo test --workspace # unit tests
cargo fmt # format code
cargo clippy # lint
lab service db --start # install + start services via hero_proc
lab service db --stop # stop all services
lab service db --status # show service status

Pre-built Binaries

Pre-built binaries are published to the Forgejo package registry:

Binary Platforms Description
hero_db_server x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu Redis-compatible server
hero_db_admin x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu Admin web dashboard

CI/CD Workflows

The Forgejo workflows (.forgejo/workflows/) build and publish on tagged releases:

  • build-linux.yaml: Builds for linux-amd64 and linux-arm64 (with UPX compression)
  • build-macos.yaml: Builds for darwin-arm64 (native macOS host)

License

Apache 2.0