NomadFlow
Server

Authentication

How authentication works in NomadFlowCode.

NomadFlowCode uses a simple shared-secret model. A single auth.secret value in config.toml secures all endpoints.

Setup

Set the secret in your configuration file (or let the setup wizard generate one for you on first run):

[auth]
secret = "your-secret-token"

When secret is empty (the default), authentication is disabled entirely. When running nomadflow serve with an empty secret, one is auto-generated for the session.

API authentication

Bearer token

All /api/* endpoints accept a Bearer token:

curl -X POST http://localhost:8080/api/list-repos \
  -H "Authorization: Bearer your-secret-token" \
  -H "Content-Type: application/json"

Basic Auth

The server also accepts HTTP Basic Authentication. The password is checked against auth.secret (the username is ignored):

curl -X POST http://localhost:8080/api/list-repos \
  -u "nomadflow:your-secret-token" \
  -H "Content-Type: application/json"

Basic Auth is particularly useful for WebView-based terminal access, where the browser handles credential prompts automatically. The server includes a WWW-Authenticate: Basic header in 401 responses to trigger the browser's native auth dialog.

Terminal WebSocket authentication

Terminal communication uses a multiplexed WebSocket at /ws/panes. Two authentication methods are supported:

Query parameter

ws://your-server:8080/ws/panes?token=your-secret-token

Subprotocol header (preferred)

Sec-WebSocket-Protocol: bearer.your-secret-token

The subprotocol method is preferred because it avoids exposing the secret in URLs and server logs. The server echoes back the protocol in its upgrade response to complete the WebSocket handshake.

The server:

  1. Validates the token (from query param or subprotocol) against auth.secret
  2. Upgrades the connection if valid
  3. Rejects invalid tokens with a 401 Unauthorized status before the upgrade completes

Security notes

  • All token comparisons use constant-time comparison via subtle::ConstantTimeEq to prevent timing attacks.
  • When using --public (tunnel mode), all traffic is encrypted via TLS. The auth secret adds a second layer of protection.

Summary

ChannelAuth methodHeader/param
API (/api/*)Bearer tokenAuthorization: Bearer <secret>
API (/api/*)Basic AuthAuthorization: Basic base64(user:password)
WebSocket (/ws/panes)Query param?token=<secret>
WebSocket (/ws/panes)SubprotocolSec-WebSocket-Protocol: bearer.<secret>

On this page