feat(busauth,client): pin the bus CA over TLS

busauth.LoadCATLSConfig turns a ca.crt path into a *tls.Config trusting only
that private CA (clients must pin it; the system roots would reject a
self-signed server cert). busauth.ServerTLSConfig loads the server keypair.
client.Options gains TLS; NewWithOptions calls nats.Secure when set, so the
data-plane connection is encrypted and the server pinned.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 12:44:13 +02:00
parent 6d3d6d2562
commit 2786ae2dde
2 changed files with 45 additions and 0 deletions
+8
View File
@@ -16,6 +16,7 @@ import (
"bytes"
"context"
"crypto/rand"
"crypto/tls"
"encoding/base64"
"encoding/hex"
"encoding/json"
@@ -66,6 +67,10 @@ type Options struct {
// with an nkey to a server that does not advertise nkey auth ("nkeys not
// supported by the server"), so this is opt-in rather than always-on.
UseNkey bool
// TLS, when non-nil, secures the NATS connection and pins the server to this
// config's RootCAs (the bus's self-signed CA). Build it with
// busauth.LoadCATLSConfig(caPath). Nil keeps the connection plaintext.
TLS *tls.Config
}
// New connects to NATS and records the control-plane URL with default Options
@@ -87,6 +92,9 @@ func NewWithOptions(natsURL, ctrlURL string, id cs.Identity, opts Options) (*Cli
}
natsOpts = append(natsOpts, nats.Nkey(nkeyPub, nkeySign))
}
if opts.TLS != nil {
natsOpts = append(natsOpts, nats.Secure(opts.TLS))
}
nc, err := nats.Connect(natsURL, natsOpts...)
if err != nil {
return nil, fmt.Errorf("client: connect nats %q: %w", natsURL, err)