Skip to content

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:

DYNODB_CREDENTIALS="AKIDEXAMPLE:your-secret,AKIDOTHER:another-secret"

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_ADDR is set, on a separate listener and mux. Bind it to a private address such as 127.0.0.1:6060 and 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 an Origin header. It never sets Access-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.