Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

Relationships

#1794 --ca-cert / SWAMP_CA_CERT are ignored when serve runs --auth-mode token — only DENO_CERT reaches the connection's TLS config (found validating #1748)

Opened by psftw · 8/23/2026

Description

When the target swamp serve runs --auth-mode token, the client's custom trust anchor is never applied: --ca-cert <pem> and SWAMP_CA_CERT are both ignored and the connection fails at the TLS handshake with

TLS certificate rejected: the server's certificate issuer is not trusted.
If using a self-signed certificate, pass it with --ca-cert /path/to/cert.pem
or set SWAMP_CA_CERT=/path/to/cert.pem

— the advice the error gives is the thing that does not work. The identical client command with the identical cert succeeds when the serve runs --auth-mode none, so the anchor is plumbed on that path and lost on the token path.

Deno's own DENO_CERT env var does reach the token path: with it set, the handshake completes and the request proceeds to WebSocket auth (the server logs WebSocket auth rejected … for a bogus token; a valid token round-trips normally). That suggests the token-auth connection is made through the default Deno fetch/WebSocket TLS stack rather than the client that receives the --ca-cert TLS options.

This bites exactly where TLS is mandatory: serve refuses off-loopback binds without TLS and without token/oauth auth, so a private direct listener (the #1748 case — the ALPN fix itself works, thanks) can only be trusted via the undocumented DENO_CERT workaround. A CA-signed leaf (proper CA:TRUE root, leaf with IP SAN + serverAuth EKU, chain served) fails identically in token mode, so it is not a self-signed-anchor quirk — the anchor simply is not installed.

Steps to reproduce

The pair below differs only in the server's --auth-mode; loopback keeps every other variable out.

swamp repo init repo --tool none
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \
  -days 2 -subj "/CN=localhost" \
  -addext "subjectAltName=IP:127.0.0.1" \
  -addext "basicConstraints=critical,CA:FALSE" \
  -keyout t.key -out t.crt

# 1) auth-mode none — --ca-cert honored
swamp serve --repo-dir repo --host 127.0.0.1 --port 9443 \
  --cert-file t.crt --key-file t.key &
swamp version --server wss://127.0.0.1:9443 --ca-cert t.crt
# -> succeeds

# 2) auth-mode token — same cert, same client command
kill %1
swamp serve --repo-dir repo --host 127.0.0.1 --port 9443 \
  --cert-file t.crt --key-file t.key \
  --auth-mode token --admins user:x &
swamp version --server wss://127.0.0.1:9443 --ca-cert t.crt
# -> TLS certificate rejected: the server's certificate issuer is not trusted
SWAMP_CA_CERT=$PWD/t.crt swamp version --server wss://127.0.0.1:9443
# -> same rejection

# 3) DENO_CERT reaches the token path
DENO_CERT=$PWD/t.crt swamp version --server wss://127.0.0.1:9443
# -> TLS completes; fails at auth as expected for a tokenless call:
#    "Authentication failed — run: swamp auth server-login ..."

Environment

  • swamp 20260822.221619.0-sha.b65edcb8 (client and server the same build)
  • Debian 13, linux amd64
  • Also reproduced with an off-loopback bind (where token mode is mandatory) and with a CA-signed chain instead of a self-signed anchor
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/23/2026, 1:15:22 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.