Sanitized, credential-free broker connection summary on BrokerDescription (GH-3269)#3272
Merged
Merged
Conversation
…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>
This was referenced Jun 29, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3269.
Summary
BrokerDescriptionpreviously captured onlyProtocolName,Name, andReplyUri. 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 returningnull;public virtualonTransportBase, 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.
host:port (vhost: …)host:port(server list ok), embedded userinfo strippedhost:portfrom the primary endpointhost:port(or websocket URI)project: <id>(+ emulator marker)null— DotPulsar's builder doesn't expose the service URLHard requirement — no credentials, ever (+ security audit)
BrokerDescription : OptionsDescriptionreflects the transport's public properties, so any credential-bearing public property is a leak. Audited each transport and closed the gaps:ProducerConfig/ConsumerConfig/AdminClientConfigwere[ChildDescription], and Confluent'sClientConfigexposesSaslUsername/SaslPassword/SslKeyPasswordas public string properties → real plaintext leak. Now[IgnoreDescription]; bootstrap servers surface viaEndpoint.NatsTransportConfiguration.ConnectionString(may embeduser:pass@) +Username/Password/Token/Jwt/NKeySeed/CredentialsFile/AuthCallbacknow[IgnoreDescription]; also suppressedResourceUri(built from the connection string) and the throwing liveConnection/JetStreamContextgetters.ManagedMqttClientOptions(carriesCredentials) now[IgnoreDescription].[IgnoreDescription].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
BrokerDescriptiontree (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