Skip to content
NarDBv0.2.0-dev

Server (nardbd)

Serving databases over gRPC with mutual TLS — certificates, configuration, grants and the audit log.

nardbd serves one or more .ndbc databases over the network. Clients connect with gRPC. The connection is always mutual TLS (mTLS): the server verifies the client's certificate and the client verifies the server's.

Setup#

Terminal
cd nardb
go build -o bin/nardbd ./cmd/nardbd

./bin/nardbd certs -dir ./certs -hosts db.example.com,10.0.0.5 -client app
./bin/nardbd example-config > nardbd.json   # edit it
./bin/nardbd serve -config nardbd.json

certs creates a certificate authority (ca.crt, ca.key), a server certificate and the first client certificate. Key files are written so that only their owner can read them (0600). ca.key can sign new clients; keep it away from the server.

Terminal
./bin/nardbd client-cert -dir ./certs -client accounting

Configuration#

JSON
{
  "listen": "127.0.0.1:7070",
  "tls_cert": "certs/server.crt",
  "tls_key": "certs/server.key",
  "client_ca": "certs/ca.crt",
  "audit_log": "nardbd-audit.log",
  "session_ttl": "8h",
  "databases": [
    {"name": "shop", "path": "data/shop.ndbc", "key": ""},
    {"name": "archive", "path": "data/archive.ndbc", "key": "passphrase-env:NARDB_ARCHIVE_PASSPHRASE"}
  ]
}
FieldNote
listenDefaults to 127.0.0.1. For any other address the server prints a warning; put a firewall in front of it.
tls_cert, tls_key, client_caRequired. The server does not run without TLS or without client certificates.
keyEmpty: unencrypted, or the key is in the system keychain. passphrase-env:NAME: passphrase from an environment variable. passphrase-file:/path: passphrase from a file (readable by its owner only).

Databases are created first with NarDB Shell or the Go API; the server does not create databases.

Users and grants#

A client authenticates as a user of the database, and every statement runs with that user's grants. Create users and grants in the shell:

Terminal
>> create_user -n app
>> grant -u app -s members -p write
>> grant -u admin -s '*' -p admin
>> revoke -u app -s members
>> show_users
PermissionAllows
readselecting with from(...)
writeread + insert_one, insert_many, update, delete
adminwrite + create_schema, alter_schema, drop_schema

-s '*' covers every schema, including ones created later. A user without grants can do nothing remotely. Every statement in a script is checked before any of them runs.

Client (Go)#

Go
import "nardb/client"

c, err := client.Dial(ctx, client.Config{
    Addr:     "db.example.com:7070",
    CAFile:   "certs/ca.crt",
    CertFile: "certs/client-app.crt",
    KeyFile:  "certs/client-app.key",
})
s, err := c.Authenticate(ctx, "shop", "app", password)
res, err := s.Exec(ctx, `from('members').where({'email': $1}).fields('name');`, email)

Values travel separately as $1, $2; they are never embedded in the query text. Large results stream in chunks of 500 rows. The contract is in nardb/proto/nardb/v1/nardb.proto; clients in other languages can be generated from it.

Security behaviour#

  • Login errors do not say whether the database, the user or the password was wrong. A missing database and a missing user are rejected in the same time as a wrong password.
  • Brute force: 5 failed logins within a minute from the same client (certificate + IP) lock that client for a minute.
  • Sessions: the token is 32 random bytes; the server keeps only its hash. It lives for session_ttl.
  • Connection limit: the database's max_connections setting caps the number of open sessions.
  • Audit log (audit_log): one JSON line per event. Each line holds the time, the event (auth_ok, auth_fail, auth_locked, exec, denied, logout), the client certificate's name, the address, the database, the user, the statement kinds and schemas, the rows affected and the duration. Query text and values are never logged.
JSON
{"time":"2026-10-30T14:39:38Z","event":"denied","client":"app","db":"shop","user":"app","statements":["drop_schema:products:admin"],"error":"nardb: permission denied: user 'app' needs admin on 'products' (line 1, col 1)"}

Not yet#

  • NarDB Shell connecting to a remote server (Connect Remote Server).
  • Certificate revocation lists (CRL); to block a client for now, remove its grants or renew the certificates with a new CA.
  • Distributing partitions to other nodes.