Authentication

View as Markdown

Every signal on DSX Exchange has a verified origin. Every subscriber is authorized for the topics it reads. This is enforced by the auth-callout service — a NATS Auth Callout that authenticates all client connections and issues topic-level permissions at connect time.

A single auth-callout instance handles authentication for both the main NATS cluster and the optional mTLS NATS cluster within each Kubernetes cluster. The auth model maps to two primary integration patterns: OAuth2 (JWT) for software clients, agents, and MCP interfaces; mTLS (X.509 client certificates) for BMS and OT devices that connect over MQTT.

Auth Flow

Auth Modes

OAuth2 (JWT/JWKS)

Clients connect with a username of oauthtoken and an access token as the password. The auth-callout validates the token against the OIDC provider’s JWKS endpoint and matches the token’s azp (authorized party) or subject claim to a permissions entry.

Configure the JWKS endpoint and issuer in the Helm values for every cluster (CSC and each CPC). Without these values, that cluster’s auth-callout cannot validate JWTs and silently rejects all OAuth2 connections:

1auth-callout:
2 serviceConfig:
3 jwks:
4 url: "https://keycloak.example.com/realms/event-bus/protocol/openid-connect/certs"
5 issuer: "https://keycloak.example.com/realms/event-bus"

mTLS (X.509 Client Certificates)

BMS and OT devices connect to the mTLS NATS endpoint (port 8883) with a client certificate. TLS is terminated at the NATS pod (the Gateway API controller uses TCP passthrough for this listener). The auth-callout extracts the certificate’s Common Name and matches it to a permissions entry.

The event-bus chart enables the mTLS endpoint by default. When global.eventBus.mtls.enabled: true, it mounts nats-mtls-server-tls into auth-callout and sets AUTH_CALLOUT_MTLS_CA_PATH automatically:

1global:
2 eventBus:
3 mtls:
4 enabled: true

NKey

Internal system components (leaf node connections, NACK controller, Surveyor) authenticate with NATS NKey signatures. Partner integrations can also use NKey auth where certificate infrastructure is not available.

NoAuth (Anonymous Fallback)

Connections that don’t match any other auth mode receive the noauth permissions. This mode is intended for development and debugging only — it should not be enabled in production deployments.

Auth Mode Identifier Reference

TypeIdentifier FieldMatched Against
oauth2azp or subjectJWT token claims validated via JWKS
mtlsidentityX.509 certificate Common Name
nkeypublic_keyNATS NKey public key
noauth(none)Anonymous access fallback

Configuring Permissions

Permissions are configured under global.eventBus.auth.permissions in the Helm values. Each entry maps an authenticated identity to a NATS account and a set of pub/sub topic rules.

1global:
2 eventBus:
3 auth:
4 permissions:
5 oauth2:
6 mqtt-client:
7 azp: "mqtt-client"
8 account: "CSC"
9 permissions:
10 pub:
11 allow: ["events.>"]
12 sub:
13 allow: ["events.>"]
14 mtls:
15 bms-gateway:
16 identity: "CN=bms.cpc-1"
17 account: "DEVICES"
18 permissions:
19 pub:
20 allow: ["sensors.>"]
21 sub:
22 allow: ["commands.>"]
23 noauth:
24 account: "ANONYMOUS"
25 permissions:
26 pub:
27 allow: ["public.>"]
28 sub:
29 allow: ["public.>"]

The chart renders this into a ConfigMap that the auth-callout pod mounts.

Permission Fields

FieldPurpose
accountNATS account the client is placed into
pub.allowSubjects the client can publish to
sub.allowSubjects the client can subscribe to
respOptional request-reply settings (max, ttl)

Subject wildcards: * matches one token, > matches one or more tokens.

Secrets Management

The auth-callout service requires three NKey seeds, provided as Kubernetes Secrets (Vault with Vault Secrets Operator is one option for managing these, but any secrets pipeline that materializes Kubernetes Secrets works):

KeySeed PrefixPublic Key PrefixPurpose
nkey-seedSUUAuth-callout connects to NATS
issuer-seedSAASigns user JWTs for authenticated clients
xkey-seedSXXEncrypts auth callout responses (optional)

Seeds are secrets and must never be stored in plain text. Public keys derived from these seeds are configured in the NATS server config. See Pre-Deployment for the full secrets inventory and generation script.

Auth Metrics

Auth-callout exposes Prometheus metrics at :9090/metrics:

MetricTypeDescription
auth_requests_totalcounterTotal auth callout requests
auth_errors_totalcounterTotal auth callout errors
auth_request_duration_secondshistogramAuth request latency
auth_oauth2_attempts_totalcounterOAuth2 auth attempts
auth_mtls_attempts_totalcountermTLS auth attempts
auth_nkey_attempts_totalcounterNKey auth attempts
auth_noauth_attempts_totalcounterNoAuth auth attempts

Each *_attempts_total metric has a corresponding *_failures_total counter.