Operations & security¶
fdyno is the data plane only. It does not terminate TLS, implement IAM, or run a management console. Run it inside a trusted boundary and configure it through environment variables.
Configuration¶
| Variable | Default | Purpose |
|---|---|---|
DYNODB_LISTEN_ADDR |
:8000 |
Data-plane listen address. |
FDB_CLUSTER_FILE |
FoundationDB default | Path to the cluster file. |
DYNODB_CREDENTIALS |
dev defaults | Extra SigV4 keyId:secret pairs (comma-separated). |
DYNODB_PPROF_ADDR |
unset (disabled) | Private address for pprof, if needed. |
DYNODB_READ_HEADER_TIMEOUT |
10s |
Slow-header (Slowloris) defense. |
DYNODB_READ_TIMEOUT |
60s |
Maximum time to read a request. |
DYNODB_WRITE_TIMEOUT |
120s |
Maximum time to write a response. |
DYNODB_IDLE_TIMEOUT |
120s |
Keep-alive idle timeout. |
Authentication¶
fdyno verifies AWS SigV4 signatures on every request against a map from access key ID to secret.
The built-in credentials are not secret
The default local, alternator, and cassandra credentials exist for
development and conformance testing. Any deployment that keeps them is
effectively unauthenticated. Set your own:
fdyno does not implement authorization: there are no IAM policies and no resource-policy enforcement. Any caller with a valid signature can access any table. Treat the network boundary as your authorization boundary.
Hardening¶
- pprof is disabled by default. It is served only when
DYNODB_PPROF_ADDRis set, on a separate listener and mux. Bind it to a private address such as127.0.0.1:6060and never expose it publicly. - HTTP timeouts are set by default to bound connection lifetime and defend against slow-client attacks; all are tunable via the variables above.
- TLS is not terminated by fdyno; run it behind a reverse proxy or load balancer that terminates TLS.
- CORS: fdyno mirrors DynamoDB and returns
Access-Control-Allow-Origin: *for requests carrying anOriginheader. It never setsAccess-Control-Allow-Credentials, and every request still requires a valid SigV4 signature, so this alone does not grant cross-origin access to data.
Deployment shape¶
flowchart LR
C["Clients"] --> LB["TLS terminator<br/>(reverse proxy / LB)"]
LB --> F1["fdyno"]
LB --> F2["fdyno"]
LB --> F3["fdyno"]
F1 --> FDB[("FoundationDB cluster")]
F2 --> FDB
F3 --> FDB
Because fdyno holds no durable state, you can run as many instances as you like behind a load balancer; they all share one consistent view through FoundationDB. Scale the FoundationDB cluster for storage and throughput.
Durability¶
All durable state lives in FoundationDB, so operational durability is FoundationDB's durability. A fdyno process can be restarted or replaced at any time without data loss. TTL configuration also survives a restart, so item expiry continues correctly. See [Transactions & consistency](tr
Throughput and latency¶
The numbers below come from cmd/perfbench against a single fdyno process backed by
a single-node FoundationDB cluster using the in-memory storage engine, on an Apple
M3 Max (14 cores), over loopback. Items are about 200 bytes with a composite key.
These are local single-node figures that show the relative cost of each operation; a
multi-node FoundationDB cluster on SSD storage behaves differently.
Eight concurrent clients:
| Operation | Throughput | p50 | p99 |
|---|---|---|---|
GetItem |
4,700 ops/s | 1.6 ms | 2.4 ms |
Query (10 items) |
3,200 ops/s | 2.5 ms | 3.5 ms |
UpdateItem |
915 ops/s | 8.0 ms | 16 ms |
PutItem |
900 ops/s | 8.0 ms | 16 ms |
A read is served by a single FoundationDB read. Write latency is dominated by
FoundationDB's commit, which is why PutItem and UpdateItem sit near 8 ms at p50
on this setup.ansactions.md#the-durable-state-invariant).
Reporting security issues¶
Please report vulnerabilities privately through the repository's GitHub Security advisories rather than a public issue.