Documentation menu

Server deployment and security

By default dynalm serve binds 127.0.0.1 and needs no authentication. To serve other machines on a trusted network, bind a non-loopback address and set an API key with --api-key-file; DynaLM refuses to start without one. DynaLM has no TLS and no per-client rate limiting, so it must not be exposed to the public internet directly — place an authenticating reverse proxy in front.

Supported deployment modes

Deployment modes
ModeBindAuthenticationStatus
Local (one user, one machine)127.0.0.1 (default)none neededSupported
Trusted LAN or servicenon-loopback --hostrequired: --api-key-file or DYNALM_API_KEYSupported
Behind an authenticating gatewaynon-loopback with --allow-unauthenticateddelegated to the gateway (TLS, auth, rate limits)Supported only when only the gateway can reach DynaLM
Public internet, directly——Not supported

Serve on a local network with an API key

openssl rand -hex 32 > ~/.dynalm/api-key
dynalm serve qwen2.5:1.5b --host 0.0.0.0 --api-key-file ~/.dynalm/api-key

Clients send Authorization: Bearer <key>. Every endpoint except GET /health requires it; the key is compared in constant time and never logged.

Built-in protections

  • Browser attacks on the local API: POST bodies must be application/json (415 otherwise) and CORS preflights are never answered, so a web page cannot drive the API cross-origin.
  • DNS rebinding: on a loopback bind, the Host header must be localhost, 127.x or [::1] (403 otherwise).
  • Resource limits: 8 MiB body limit, validated max_tokens, at most --max-active concurrent completions (then 503 with Retry-After), a 600 s default request timeout, and prompt length checked against KV capacity.
  • Untrusted model files: the GGUF and SafeTensors parsers bounds-check sizes and offsets and are mutation-fuzzed in CI under ASan and UBSan. Chat templates in model metadata are never executed.
  • Shutdown endpoint: POST /admin/shutdown is loopback-only and can be turned off with --disable-admin.

Run in Docker

docker run --rm -d -p 127.0.0.1:8000:8000 -v "$PWD/models:/models" \
  ghcr.io/dynalm-project/dynalm:cpu serve /models/qwen3-4b.gguf --allow-unauthenticated

Caution Inside a container the server binds a non-loopback address, which is why the example uses --allow-unauthenticated and publishes the port on 127.0.0.1 only. If you publish it more widely, use --api-key-file or a gateway instead.

Health checks and monitoring

GET /health returns 200 when ready and 503 while draining, which suits container liveness probes. GET /metrics exposes Prometheus counters and histograms for requests, time to first token, inter-token latency, tokens, KV block use, prefix-cache hits and resident memory. On shutdown the server stops accepting work and finishes in-flight requests for up to --shutdown-timeout seconds (default 30).

Frequently asked questions

Can I expose DynaLM to the internet?

Not directly. Put a reverse proxy that provides TLS, authentication and rate limiting in front, and make sure only the proxy can reach DynaLM.

How do I report a security issue?

Follow the process in the repository’s SECURITY.md rather than opening a public issue.

Source: docs/security.md (opens in a new tab), docs/deployment.md (opens in a new tab), SECURITY.md (opens in a new tab)