moltendb-server 0.9.0

MoltenDB HTTP server โ€” Axum routing, TLS, auth, rate limiting, CORS.
Documentation

moltendb-server

๐Ÿš€ The Network Layer Crate

Axum HTTP server ยท TLS ยท Scoped JWT auth ยท Token delegation ยท CORS ยท Rate limiting ยท WebSocket ยท CLI config
The runnable binary. Delegates all database logic to moltendb-core.

License Rust Tests


What is this crate?

moltendb-server is the runnable binary of MoltenDB. It owns everything related to the network layer and leaves all database logic to moltendb-core:

  • Axum HTTP server with TLS termination (axum-server + rustls).
  • Unified Configuration โ€” Owns the CLI flags and environment variable parsing logic. It populates the core engine's DbConfig from these inputs.
  • REST endpoints โ€” POST /set, POST /get, POST /update, POST /delete, POST /snapshot, POST /analytics (โš ๏ธ analytics under development).
  • REST-style GET โ€” GET /collections/:collection/docs/:key and GET /collections/:collection (paginated).
  • Token delegation โ€” POST /auth/delegate (root-only) mints narrow-scoped JWTs for clients; every endpoint enforces scopes on every request.
  • WebSocket โ€” GET /ws for real-time mutation notifications.
  • CLI Utility โ€” moltendb recover subcommand for Point-in-Time Recovery.
  • JWT auth middleware โ€” all protected routes require a valid Authorization: Bearer <token> header; scopes are checked per-endpoint.
  • Per-IP rate limiting โ€” sliding-window rate limiter, configurable via CLI.
  • CORS โ€” configurable allowed origins.
  • Request body size limit โ€” oversized requests are rejected at the HTTP layer before application code sees them.
  • Graceful shutdown โ€” drains in-flight requests and flushes the WAL before exit.
  • CLI configuration โ€” all options are configurable via clap flags or environment variables.

Quick start

Install from source

cargo install --path moltendb-server

Run

moltendb \

  --db-path my_database.log \

  --write-mode async \

  --storage-mode tiered \

  --jwt-secret my-awesome-secret \

  --root-user admin \

  --root-password admin123 \

  --cors-origin "*"

Or with cargo run from the workspace root:

cargo run --package moltendb-server --bin moltendb -- \

  --db-path my_database.log \

  --write-mode async \

  --storage-mode tiered \

  --jwt-secret my-awesome-secret \

  --root-user admin \

  --root-password admin123 \

  --cors-origin "*"


CLI reference

All options can be set via CLI flags or environment variables. CLI flags take priority.

Note: Networking and authentication flags are exclusive to the server binary. If you use moltendb-core as a library, you must configure it programmatically via DbConfig.

Flag Env var Default Description
--cert MOLTENDB_TLS_CERT cert.pem TLS certificate PEM file
--cors-origin MOLTENDB_CORS_ORIGIN * Allowed CORS origin(s), comma-separated
--db-path MOLTENDB_DB_PATH my_database.log Path to the WAL log file
--debug MOLTENDB_DEBUG false Enable verbose debug logging
--disable-encryption MOLTENDB_DISABLE_ENCRYPTION false Disable at-rest encryption
--encryption-key MOLTENDB_ENCRYPTION_KEY โ€” At-rest encryption password (ChaCha20-Poly1305)
--hot-threshold MOLTENDB_HOT_THRESHOLD 50000 Number of documents per collection kept in RAM before paging out to disk
--jwt-secret MOLTENDB_JWT_SECRET required JWT signing secret โ€” server refuses to start without it
--key MOLTENDB_TLS_KEY key.pem TLS private key PEM file
--max-body-size MOLTENDB_MAX_BODY_SIZE 10485760 Max request body size in bytes (default 10 MB)
--port MOLTENDB_PORT 1538 Port to listen on
--post-backup-script MOLTENDB_POST_BACKUP_SCRIPT None Path to a script file to run after backup
--rate-limit-requests MOLTENDB_RATE_LIMIT_REQS 100 Max requests per IP per window
--rate-limit-window MOLTENDB_RATE_LIMIT_WINDOW 60 Rate limit sliding window in seconds
--root-password MOLTENDB_ROOT_PASSWORD โ€” Root password seeded at startup
--root-user MOLTENDB_ROOT_USER โ€” Root username seeded at startup
--storage-mode MOLTENDB_STORAGE_MODE standard standard or tiered (hot + cold log, recommended for 100k+ docs)
--write-mode MOLTENDB_WRITE_MODE async async or sync

Point-in-Time Recovery (PITR)

MoltenDB supports recovering the database to any millisecond or sequence number.

Via CLI

# Recover to a specific Unix timestamp (milliseconds)

moltendb recover --log my_database.log --to-time 1713972000000 --out recovered.snapshot.bin


# Recover to a specific log sequence number

moltendb recover --log my_database.log --to-seq 5000 --out recovered.snapshot.bin

To use the recovered state, rename recovered.snapshot.bin to my_database.log.snapshot.bin and restart the server.

Manual Snapshot

You can trigger an on-demand snapshot via the API. This is useful before performing risky operations.

POST /snapshot
Authorization: Bearer <jwt>

HTTP API

Authentication & Token Delegation

POST /login
Content-Type: application/json

{ "username": "admin", "password": "admin123" }

Returns { "token": "<jwt>" }. The root token carries the *:*:* scope (full admin access). Include it in all subsequent requests:

Authorization: Bearer <jwt>

Delegate a scoped token (POST /auth/delegate)

The root user can mint narrow-permission JWTs for clients. Only the root user can call this endpoint.

POST /auth/delegate
Authorization: Bearer <root-jwt>
Content-Type: application/json

{
  "client_id": "laptop-service",
  "scopes": ["read:laptops:*", "write:laptops:*"],
  "ttl_secs": 3600
}

Returns { "token": "<scoped-jwt>", "jti": "<uuid>", "client_id": "laptop-service", "scopes": [...] }. Save the jti โ€” you will need it to revoke this token.

Scope format: action:collection:document_key

Scope Meaning
read:laptops:lp1 Read only document lp1 in laptops
read:laptops:* Read any document in laptops
write:laptops:* Write any document in laptops
delete:laptops:* Delete any document in laptops
read:*:* Read any document in any collection
*:*:* Full admin โ€” root only

Every endpoint enforces scopes. A token missing the required scope receives 403 Forbidden.

Revoke a token (DELETE /auth/tokens/:jti)

Immediately invalidates a JWT before its TTL expires. Requires a *:*:* (admin) token.

DELETE /auth/tokens/da5e155d-6a47-48eb-9cc3-7fc440cd2e39
Authorization: Bearer <admin-jwt>
Content-Type: application/json

{ "exp": 1777562342 }

The exp value is the Unix timestamp from the token's payload โ€” used as the prune deadline so the revocation entry is cleaned up automatically once the token would have expired anyway. The revocation store is persisted to <db-path>.revocations.json and reloaded on server restart, so revocations survive restarts.

To extract the jti from a token, decode the middle segment of the JWT (base64url) or read it directly from the POST /auth/delegate response.

Insert / upsert

POST /set
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "collection": "users",
  "data": {
    "u1": { "name": "Alice", "role": "admin" },
    "u2": { "name": "Bob",   "role": "viewer" }
  }
}

Query

POST /get
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "collection": "users",
  "where": { "role": "admin" },
  "fields": ["name", "role"],
  "sort": [{ "field": "name", "order": "asc" }],
  "count": 10,
  "offset": 0
}

Update (partial patch)

POST /update
Authorization: Bearer <jwt>
Content-Type: application/json

{ "collection": "users", "data": { "u1": { "role": "superadmin" } } }

Delete

POST /delete
Authorization: Bearer <jwt>
Content-Type: application/json

{ "collection": "users", "keys": "u1" }

REST-style GET

# Fetch a single document (requires read:users:u1 or read:users:* or *:*:*)
GET /collections/users/docs/u1
Authorization: Bearer <jwt>

# Fetch all documents in a collection (requires read:users:* or *:*:*)
GET /collections/users?limit=100&offset=0
Authorization: Bearer <jwt>

WebSocket

wss://localhost:1538/ws

Emits a JSON message for every mutation:

{ "event": "change", "collection": "users", "key": "u1", "new_v": 2 }

Testing

A full API walkthrough โ€” including all six privilege levels from document-level read to full admin โ€” is available in tests/requests.http. Run it with any HTTP client that supports .http files (JetBrains HTTP Client, REST Client for VS Code, etc.).

For a quick test, start the server with --root-user admin --root-password admin123, log in via POST /login, and paste the token into the @token variable at the top of the file.


Making auth optional

moltendb-auth handles all identity concerns โ€” JWT minting, Argon2 hashing, scope enforcement. MoltenDB is designed to work alongside your own user table: your backend validates credentials against your database, then calls POST /auth/delegate with the root token to mint a scoped JWT for the client. The root token never leaves your backend.

See the moltendb-auth README for the full integration pattern and scope reference.


Part of the MoltenDB workspace

MoltenDB/
โ”œโ”€โ”€ moltendb-core/     โ€” pure engine (DashMap, WAL, query evaluator)
โ”œโ”€โ”€ moltendb-wasm/     โ€” browser adapter (wasm-bindgen glue, WorkerDb, OPFS)
โ”œโ”€โ”€ moltendb-auth/     โ€” identity layer (JWT, Argon2, UserStore)
โ””โ”€โ”€ moltendb-server/   โ† you are here

See the root README for the full architecture overview and feature list.