Skip to main content

ServerCertificateTrust

Namespace: Meshmakers.Octo.Sdk.ServiceClient

The one switch that decides whether this process validates the TLS certificates of the Octo services it calls (AB#5303 items 1 and 2).

public static class ServerCertificateTrust

Inheritance Object → ServerCertificateTrust

Remarks:

🔴 Process-wide on purpose, and static on purpose. Whether a private or self-signed certificate can be trusted is a property of the machine the process runs on, not of an individual client object — and the SDK reaches its services through four unrelated HTTP stacks (SignalR, RestSharp, GraphQL.Client, and bare HttpClient plus Duende's discovery cache), each with its own injection point and none of them sharing options. A per-options flag would have to be threaded through all four and could disagree with itself; one gate cannot.

🔴 What this replaces. Two mechanisms, neither of which worked as its name says. SignalRClient attached ServerCertificateCustomValidationCallback => true to every hub connection unconditionally — no #if, no option, in every environment including production, under a comment reading "always verify the SSL certificate". Meanwhile AdapterOptions.IgnoreCertificateValidation set ServicePointManager.ServerCertificateValidationCallback, which SocketsHttpHandler has ignored since .NET Core: setting it changed nothing, as a running pool member demonstrated. So the hub connection was unverified everywhere and the switch meant to control that was inert — the reason a member could reach the controller over a dev certificate while its OIDC discovery failed on the very same one.

Production is refused, unknown is allowed. The gate reads ASPNETCORE_ENVIRONMENT / DOTNET_ENVIRONMENT and declines only when one of them explicitly says Production. An unset environment — which is most adapter pods — is allowed and logs a warning naming the switch, because refusing there would silently take out every dev cluster that never set the variable, and a bypass nobody can see is the defect this whole item is about.

Properties​

AllowsAnyServerCertificate​

Whether this process currently accepts any server certificate. False unless a host has called ServerCertificateTrust.AllowAnyServerCertificate(ILogger) and the environment permitted it.

public static bool AllowsAnyServerCertificate { get; }

Property Value​

Boolean

ValidationCallback​

The validation callback for stacks that take one instead of a handler (RestSharp).

public static RemoteCertificateValidationCallback ValidationCallback { get; }

Property Value​

RemoteCertificateValidationCallback

Methods​

AllowAnyServerCertificate(ILogger)​

Turns certificate validation off for every HTTP stack in this process. Called by a host that was configured with IgnoreCertificateValidation.

public static bool AllowAnyServerCertificate(ILogger logger)

Parameters​

logger ILogger
Receives the warning, or the refusal. Optional.

Returns​

Boolean
true when the bypass is now in force; false when the environment refused it, in which case the process keeps validating.

ResetForTests()​

Resets the gate. Test-only: the gate is process-wide state, and a test that turns it on would otherwise leak into every test that runs after it.

internal static void ResetForTests()

CreateHandler()​

A handler honouring the gate. Always a fresh instance — handlers carry connection pools and sharing one across clients with different lifetimes is its own defect.

public static HttpMessageHandler CreateHandler()

Returns​

HttpMessageHandler

CreateHttpClient()​

An over ServerCertificateTrust.CreateHandler().

public static HttpClient CreateHttpClient()

Returns​

HttpClient

Apply(HttpMessageHandler)​

Applies the gate to a handler somebody else built — the shape SignalR and RestSharp hand us. Leaves the handler untouched while the gate is closed, so the platform default applies.

public static HttpMessageHandler Apply(HttpMessageHandler handler)

Parameters​

handler HttpMessageHandler

Returns​

HttpMessageHandler