Philosophy
DocumentForge is a database, not an identity platform. We provide three simple knobs that cover the common cases — bearer-token auth on the REST API, a shared secret for replication handshakes, and TLS for encrypted transport. Everything else (user accounts, RBAC, OAuth, OIDC) is better handled by an API gateway in front of DocumentForge.
By default everything is off. This keeps the dev loop friction-free. Turn knobs on individually as you go to production.
Threat model
| Surface | Default | With all knobs on |
|---|---|---|
| REST API | Open (localhost only by default) | Bearer-token auth, TLS |
| Replication protocol | No handshake secret | Shared secret required |
| Cluster inter-shard (HTTP) | Plain HTTP | TLS + bearer token |
| Data file on disk | OS file permissions | OS file permissions + disk encryption (your job) |
Knob 1 — API key (bearer token)
If set, every HTTP request must include:
Authorization: Bearer <your-api-key>
Configure a node
{
"nodeName": "shard-a",
"port": 5001,
"dataDir": "./data/shard-a",
"security": {
"apiKey": "sk_prod_abc123xyz"
}
}
Or via CLI / env:
dfdb serve --node-name shard-a --port 5001 --api-key sk_prod_abc123xyz
# or
DFDB_API_KEY=sk_prod_abc123xyz dfdb serve
From the admin UI
Go to Settings, paste the key. It's stored in localStorage and attached to every fetch. Works offline across page loads.
From your application
using var cluster = DocumentForgeCluster.FromConfig(config, desc => new HttpShardTransport(desc.Name, desc.LeaderEndpoint, apiKey: "sk_prod_abc123xyz"));
The constant-time compare ensures timing attacks don't leak partial-match information.
Knob 2 — Replication secret
Before a follower starts receiving streamed operations from a leader, it presents a shared secret. Mismatch = connection dropped. Prevents attackers on your network from pretending to be followers (siphoning every write) or leaders (injecting fake writes).
{
"security": {
"replicationSecret": "rp_xyz789abc"
}
}
The leader and every follower must agree on the same secret. In C# code:
leader.StartLogicalReplicationServer(port: 5500, sharedSecret: "rp_xyz789abc"); follower.StartLogicalReplicationFollower("leader-host", 5500, sharedSecret: "rp_xyz789abc");
Knob 3 — TLS
ASP.NET Kestrel handles this; point at a PFX cert file.
{
"security": {
"tls": {
"certPath": "./certs/node.pfx",
"certPassword": "env:TLS_PASSWORD"
}
}
}
When certPassword starts with env:, the value is read from that environment variable at startup — keeps secrets out of config files.
The URL scheme flips to https://. Point clients (including the admin UI) at the HTTPS URL.
Network hygiene
- By default, the API binds to localhost only. Add
"bindAllInterfaces": true(or--bind-all) to open it to other hosts. - Only open the replication port to other nodes in your cluster — never to the public internet.
- Run nodes inside a VPN, service mesh, or a private network whenever possible. Defense in depth.
Data at rest
DocumentForge does not encrypt data files. This is intentional — OS-level disk encryption is available, well-audited, and better than anything we'd ship.
- Windows: BitLocker on the volume holding your
.dfdbfiles - Linux: LUKS or dm-crypt
- macOS: FileVault
- Cloud: AWS EBS encryption, GCP persistent disk encryption, Azure Disk encryption — all transparent
Production checklist
- ✓ API key set on every node
- ✓ Replication secret set on every node participating in replication
- ✓ TLS enabled on every node (or traffic stays strictly internal)
- ✓ Firewall: only expose replication port to other cluster members
- ✓ API port exposed only to approved clients (app servers, admin UI)
- ✓ OS-level disk encryption enabled on data volumes
- ✓ Backup mechanism does not copy unencrypted files off the encrypted volume
- ✓ Secrets (API key, replication secret, TLS password) stored in a secret manager, not in the config file
- ✓ Rotate the API key and replication secret on a schedule
What we don't build (and where to go)
| Need | Where to get it |
|---|---|
| User accounts / RBAC | Auth0, Keycloak, AWS Cognito in front of the API |
| OAuth / OIDC / SAML | Same — an API gateway terminates and forwards |
| Field-level encryption | Application layer (encrypt before insert) |
| Key rotation automation | HashiCorp Vault, AWS Secrets Manager, Azure Key Vault |
| Data-at-rest encryption | OS disk encryption (above) |
| Audit logging to SIEM | Tap the REST API proxy / gateway you deploy in front |
| Rate limiting / quotas | API gateway (Kong, Tyk, Envoy) |
Replication_SharedSecretEnforced — a follower with the right secret connects successfully and receives ops; a follower with the wrong secret is rejected and sees zero ops. Invariant: an attacker can't siphon writes or inject fake ones without the secret.