HTTP Server

The HTTP server (http.service) listens on a port and hosts routers, endpoints, and static file handlers.

Configuration

- name: gateway
  kind: http.service
  addr: ":8080"
  timeouts:
    read: "5s"
    write: "30s"
    idle: "60s"
  host:
    buffer_size: 1024
    worker_count: 4
  lifecycle:
    auto_start: true
    security:
      actor:
        id: "http-gateway"
      policies:
        - app:http_policy
Field Type Default Description
addr string required Listen address (:8080, 0.0.0.0:443)
timeouts.read duration - Request read timeout
timeouts.write duration - Response write timeout
timeouts.idle duration - Keep-alive connection timeout
host.buffer_size int 1024 Message relay buffer size
host.worker_count int NumCPU Message relay workers
network Registry ID - Bind listener through a network overlay (e.g. Tailscale, I2P)
tls object - TLS termination (see TLS)

Timeouts

Configure timeouts to prevent resource exhaustion:

timeouts:
  read: "10s"    # Max time to read the entire request (headers + body)
  write: "60s"   # Max time to write response
  idle: "120s"   # Keep-alive timeout
  • read - Short (5-10s) for APIs, longer for uploads
  • write - Match expected response generation time
  • idle - Balance connection reuse vs resource usage
Duration format: 30s, 1m, 2h15m. Use 0 to disable.

Host Configuration

The host section configures the server's internal message relay used by components like WebSocket relay:

host:
  buffer_size: 2048
  worker_count: 8
Field Default Description
buffer_size 1024 Message queue capacity per worker
worker_count NumCPU Parallel message processing goroutines
Increase these values for high-throughput WebSocket applications. The message relay handles async delivery between HTTP components and processes.

Security

HTTP servers can have a default security context applied through the lifecycle configuration:

lifecycle:
  auto_start: true
  security:
    actor:
      id: "gateway-service"
    policies:
      - app:http_access_policy

This sets a baseline actor and policies for all requests. For authenticated requests, the token_auth middleware overrides the actor based on the validated token, allowing per-user security policies.

Lifecycle

Servers are managed by the supervisor:

lifecycle:
  auto_start: true
  start_timeout: 30s
  stop_timeout: 60s
  depends_on:
    - app:database
Field Description
auto_start Start when application starts
start_timeout Max time to wait for server to start
stop_timeout Max time for graceful shutdown
depends_on Start after these entries are ready

Connecting Components

Routers and static handlers reference the server via metadata:

entries:
  - name: gateway
    kind: http.service
    addr: ":8080"

  - name: api
    kind: http.router
    meta:
      server: gateway
    prefix: /api

  - name: static
    kind: http.static
    meta:
      server: gateway
    path: /
    fs: app:public

Multiple Servers

Run separate servers for different purposes:

entries:
  # Public API
  - name: public
    kind: http.service
    addr: ":8080"
    lifecycle:
      auto_start: true

  # Admin (localhost only)
  - name: admin
    kind: http.service
    addr: "127.0.0.1:9090"
    lifecycle:
      auto_start: true

TLS

The server can terminate TLS directly. Set tls.mode to manual (supply your own certificate) or auto (certificate provided by an overlay network driver, e.g. network.tailscale). Plain clearnet listeners do not support auto. Omit tls or leave the mode empty to run plain HTTP.

In auto mode the server must not specify cert/key — the network driver provides them.

Manual certificate

Under mode: manual, cert and key carry PEM content. Supply that content in one of three ways (pick one per field, never mix):

  1. Inline PEM — the literal PEM string.
  2. file:// reference — manifest-relative path, resolved and inlined at load time (traversal-safe).
  3. Environment registry reference — pull the PEM from a registered env variable at decode time, using a ${env:NAME} placeholder.
- name: api
  kind: http.service
  addr: ":443"
  tls:
    mode: manual
    cert: file://./certs/server.pem
    key:  file://./certs/server.key
- name: api
  kind: http.service
  addr: ":443"
  tls:
    mode: manual
    cert: ${env:app.env:tls_cert}
    key:  ${env:app.env:tls_key}

The ${env:NAME} placeholder resolves NAME through the environment registry — a registered variable's public name or its entry ID (e.g. app.env:tls_cert). It is not a raw OS environment variable; an OS value is only reachable when an env.storage.os-backed variable is registered under that name. A default can be supplied with ${env:NAME|default}.

The legacy cert_env / key_env companion fields still resolve through the environment registry the same way, but are deprecated — prefer the ${env:NAME} placeholder shown above.
Field Description
mode "" (off), auto, or manual
cert / key PEM content — inline, file:// reference, or ${env:NAME} placeholder

Mutual TLS (mTLS)

Under mode: manual the server can additionally verify client certificates:

tls:
  mode: manual
  cert: ${env:app.env:tls_cert}
  key:  ${env:app.env:tls_key}
  client_ca: file://./certs/clients-ca.pem
  client_auth: require_and_verify

client_ca accepts the same three forms as cert/key (inline PEM, file://, or ${env:NAME}). The legacy client_ca_env companion field is likewise deprecated in favor of client_ca: ${env:NAME}.

Field Description
client_auth request, require_any, verify_if_given, require_and_verify
client_ca PEM bundle of trusted client CAs (inline, file://, or ${env:NAME})

verify_if_given and require_and_verify require a CA. request and require_any accept any client cert without CA verification.

See Also