# MQTT Connection Type Port Design ## Goal Port MQTT-related connection type parity from Go into the .NET server for two scoped areas: 1. JWT `allowed_connection_types` behavior for `MQTT` / `MQTT_WS` (plus existing known types). 2. `/connz` filtering by `mqtt_client`. ## Scope - In scope: - JWT allowed connection type normalization and enforcement semantics. - `/connz?mqtt_client=` option parsing and filtering. - Unit/integration tests for new and updated behavior. - `differences.md` updates after implementation is verified. - Out of scope: - Full MQTT transport implementation. - WebSocket transport implementation. - Leaf/route/gateway transport plumbing. ## Architecture - Add an auth-facing connection-type model that can be passed through `ClientAuthContext`. - Implement Go-style allowed connection type conversion and matching in `JwtAuthenticator`: - normalize input to uppercase. - retain recognized types. - collect unknown types as non-fatal if at least one valid type remains. - reject when only unknown types are present. - enforce current connection type against the resulting allowed set. - Extend connz monitoring options to parse `mqtt_client` and apply exact-match filtering before sort/pagination. ## Components - `src/NATS.Server/Auth/IAuthenticator.cs` - Extend `ClientAuthContext` with a connection-type value. - `src/NATS.Server/Auth/Jwt/JwtConnectionTypes.cs` (new) - Canonical constants for known connection types: - `STANDARD`, `WEBSOCKET`, `LEAFNODE`, `LEAFNODE_WS`, `MQTT`, `MQTT_WS`, `INPROCESS`. - Helper(s) for normalization and validation behavior. - `src/NATS.Server/Auth/JwtAuthenticator.cs` - Evaluate `userClaims.Nats?.AllowedConnectionTypes` using Go-compatible semantics. - Enforce against current `ClientAuthContext.ConnectionType`. - `src/NATS.Server/NatsClient.cs` - Populate auth context connection type (currently `STANDARD`). - `src/NATS.Server/Monitoring/Connz.cs` - Add `MqttClient` to `ConnzOptions` with JSON field `mqtt_client`. - `src/NATS.Server/Monitoring/ConnzHandler.cs` - Parse `mqtt_client` query param. - Filter connection list by exact `MqttClient` match when provided. - `src/NATS.Server/Monitoring/ClosedClient.cs` - Add `MqttClient` field to closed snapshots. - `src/NATS.Server/NatsServer.cs` - Persist `MqttClient` into `ClosedClient` snapshot (empty for now). ## Data Flow 1. Client sends `CONNECT`. 2. `NatsClient.ProcessConnectAsync` builds `ClientAuthContext` with `ConnectionType=STANDARD`. 3. `AuthService` invokes `JwtAuthenticator` for JWT-based auth. 4. `JwtAuthenticator`: - converts `allowed_connection_types` to valid/unknown buckets. - rejects unknown-only lists. - enforces connection-type membership when valid list is non-empty. 5. Monitoring request `/connz`: - `ConnzHandler.ParseQueryParams` reads `mqtt_client`. - open/closed conn rows are materialized. - rows are filtered on exact `MqttClient` when filter is present. - sorting and pagination run on filtered results. ## Error Handling and Compatibility - Auth failures remain non-throwing (`Authenticate` returns `null`). - Unknown connection type tokens in JWT are tolerated only when at least one known allowed type remains. - Unknown-only allowed lists are rejected to avoid unintended allow-all behavior. - `mqtt_client` query parsing is lenient and string-based; empty filter means no filter. - Existing JSON schema compatibility is preserved. ## Current Runtime Limitation (Explicit) - MQTT transport is not implemented yet in this repository. - Runtime connection type currently resolves to `STANDARD` in auth context. - `mqtt_client` values remain empty until MQTT path populates them. ## Testing Strategy - `tests/NATS.Server.Tests/JwtAuthenticatorTests.cs` - allow `STANDARD` for current client context. - reject `MQTT` for current client context. - allow mixed known+unknown when current type is known allowed. - reject unknown-only list. - validate case normalization behavior. - `tests/NATS.Server.Tests/MonitorTests.cs` - `/connz?mqtt_client=` returns matching connections only. - `/connz?state=closed&mqtt_client=` filters closed snapshots. - non-existing ID yields empty connection set. ## Success Criteria - JWT `allowed_connection_types` behavior matches Go semantics for known/unknown mixing and unknown-only rejection. - `/connz` supports exact `mqtt_client` filtering for open and closed sets. - Added tests pass. - `differences.md` accurately reflects implemented parity.