Skip to content

Sanitized, credential-free broker connection summary on BrokerDescription (GH-3269)#3272

Merged
jeremydmiller merged 1 commit into
mainfrom
feat/broker-connection-summary-3269
Jun 28, 2026
Merged

Sanitized, credential-free broker connection summary on BrokerDescription (GH-3269)#3272
jeremydmiller merged 1 commit into
mainfrom
feat/broker-connection-summary-3269

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Closes #3269.

Summary

BrokerDescription previously captured only ProtocolName, Name, and ReplyUri. A monitoring console (CritterWatch's messaging topology) wants a human-readable "what is this broker pointing to" summary — but only the transport knows its connection target.

This adds:

  • ITransport.DescribeEndpoint() — default interface member returning null; public virtual on TransportBase, overridden per transport.
  • BrokerDescription.Endpoint — captures it.

The summary is built from parsed connection components only — host/port/vhost/namespace/region/bootstrap-servers — never from a raw connection string.

Transport Summary
RabbitMQ host:port (vhost: …)
Azure Service Bus namespace FQDN
Amazon SQS / SNS region (or explicit ServiceURL, e.g. LocalStack)
Kafka bootstrap servers
NATS host:port (server list ok), embedded userinfo stripped
Redis host:port from the primary endpoint
MQTT broker host:port (or websocket URI)
GCP Pub/Sub project: <id> (+ emulator marker)
Pulsar null — DotPulsar's builder doesn't expose the service URL

Hard requirement — no credentials, ever (+ security audit)

BrokerDescription : OptionsDescription reflects the transport's public properties, so any credential-bearing public property is a leak. Audited each transport and closed the gaps:

  • KafkaProducerConfig/ConsumerConfig/AdminClientConfig were [ChildDescription], and Confluent's ClientConfig exposes SaslUsername/SaslPassword/SslKeyPassword as public string properties → real plaintext leak. Now [IgnoreDescription]; bootstrap servers surface via Endpoint.
  • NATSNatsTransportConfiguration.ConnectionString (may embed user:pass@) + Username/Password/Token/Jwt/NKeySeed/CredentialsFile/AuthCallback now [IgnoreDescription]; also suppressed ResourceUri (built from the connection string) and the throwing live Connection/JetStreamContext getters.
  • MQTTManagedMqttClientOptions (carries Credentials) now [IgnoreDescription].
  • GCP — the three builder-callback properties now [IgnoreDescription].
  • RabbitMQ / Azure / Pulsar / Redis credential properties were already suppressed (verified).

Tests

Per-transport unit tests (9 transports, 24 methods) asserting the summary is correct and that a sentinel secret never appears anywhere in the reflected BrokerDescription tree (Properties / Children / Sets). The scan caught two real issues during development (Kafka SASL leak; a NATS getter that threw during reflection). Existing CoreTests capability/broker suite still green.

🤖 Generated with Claude Code

…y on BrokerDescription (GH-3269)

Adds ITransport.DescribeEndpoint() (default null, overridable on TransportBase) and
captures it into a new BrokerDescription.Endpoint property so a monitoring console
(CritterWatch's messaging topology) can show what each broker points to. The summary
is built from parsed connection components only — host/port/vhost/namespace/region/
bootstrap-servers — and NEVER from a raw connection string.

Per-transport summaries:
- RabbitMQ: host:port (vhost: …) from the connection factory
- Azure Service Bus: the namespace FQDN
- Amazon SQS/SNS: region (or an explicit ServiceURL, e.g. LocalStack)
- Kafka: bootstrap servers
- NATS: host:port (server list supported), with embedded userinfo stripped
- Redis: host:port from the primary endpoint
- MQTT: broker host:port (or websocket URI)
- GCP Pub/Sub: project id (+ emulator marker)
- Pulsar: null (DotPulsar's builder does not expose the service URL)

Credential-leak audit (BrokerDescription : OptionsDescription reflects the transport's
public properties):
- Kafka: ProducerConfig/ConsumerConfig/AdminClientConfig were [ChildDescription] and
  Confluent's ClientConfig exposes SaslUsername/SaslPassword/SslKeyPassword as public
  string properties — now [IgnoreDescription]. Bootstrap servers move to Endpoint.
- NATS: NatsTransportConfiguration's ConnectionString (may embed userinfo) + Username/
  Password/Token/Jwt/NKeySeed/CredentialsFile/AuthCallback now [IgnoreDescription];
  ResourceUri (built from the connection string) and the throwing live Connection /
  JetStreamContext getters suppressed too.
- MQTT: ManagedMqttClientOptions (carries Credentials) now [IgnoreDescription].
- GCP: the three builder-callback properties now [IgnoreDescription].

Tests: per-transport unit tests asserting the summary is correct AND that a sentinel
secret never appears anywhere in the reflected BrokerDescription tree (Properties /
Children / Sets). 9 transports covered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit 2c804f8 into main Jun 28, 2026
26 checks passed
This was referenced Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BrokerDescription: add a sanitized, credential-free connection summary per transport

1 participant