Skip to content

Add per-certificate mTLS HTTP client factory - #671

Open
Robbie-Microsoft wants to merge 6 commits into
rginsburg/mtls-pop-featurefrom
robbie-microsoft-per-certificate-mtls-factory
Open

Robbie-Microsoft wants to merge 6 commits into
rginsburg/mtls-pop-featurefrom
robbie-microsoft-per-certificate-mtls-factory

Conversation

@Robbie-Microsoft

@Robbie-Microsoft Robbie-Microsoft commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds per-certificate mTLS client construction for HTTP adapters that own middleware. #669's one-time Service Fabric use of managedidentity.ClientConfigurer remains unchanged. Confidential clients use the same released configuration contract on fresh adapters because certificates can rotate or be selected concurrently.

API and behavior

  • Adds public confidential.HTTPClient, confidential.ClientConfigurer, and confidential.MtlsHTTPClientFactory contracts. confidential.ClientConfigurer aliases the released managedidentity.ClientConfigurer; the factory capability is detected on the value passed to confidential.WithHTTPClient.
  • NewMtlsClient() (ClientConfigurer, error) returns a fresh, independently configurable adapter. MSAL calls its ConfigureClient method with an augmenter closed over the selected certificate snapshot. The original factory, shared client, and shared transport are not mutated.
  • The augmenter clones the supplied base client and transport, preserving application proxy routing, dialers, roots, timeouts, pool settings, middleware, and logging. MSAL owns the binding certificate, TLS minimum, TLS session isolation, and redirect policy on the clone.
  • The same certificate reuses one published cached adapter. Different certificates use isolated adapters, transports, connection pools, and TLS sessions. Concurrent initial misses for the same certificate may construct multiple adapters; one is published and the losers are closed.
  • The direct *http.Client path is unchanged. Generation fencing, cache-capacity cleanup, redirect refusal and override behavior, and idle-connection cleanup remain in place.

Contract

  • MSAL rejects nil factory results; requires exactly one synchronous augmenter call with a non-nil base *http.Client; rejects missing, repeated, or late calls; and propagates factory, ConfigureClient, and augmenter errors.
  • The configurer must ensure Do terminates through the augmented client and CloseIdleConnections reaches its connection pool. MSAL cannot inspect arbitrary middleware to verify those obligations.
  • A typed-nil *http.Transport is rejected before request transmission.

Scope and validation

@Robbie-Microsoft
Robbie-Microsoft changed the base branch from robbie-microsoft-prepare-661-after-669 to rginsburg/mtls-pop-feature September 17, 2026 21:18
@Robbie-Microsoft
Robbie-Microsoft force-pushed the robbie-microsoft-per-certificate-mtls-factory branch from 2fcbd46 to 0da7e13 Compare September 17, 2026 21:18
@sonarqubecloud

Copy link
Copy Markdown

@Robbie-Microsoft
Robbie-Microsoft force-pushed the robbie-microsoft-per-certificate-mtls-factory branch 2 times, most recently from 39a5818 to fa2a45e Compare September 17, 2026 21:35
Expose HTTPClient and MtlsHTTPClientFactory through WithHTTPClient so adapters can build middleware-backed clients around an MSAL-owned, certificate-snapshot augmenter that installs the certificate and security policy.

Reuse comm.Client's per-certificate cache so the same certificate shares a client while different certificates isolate transports, pools, and TLS sessions. Validate synchronous factory augmentation, fail closed on invalid callback behavior or transports, and close discarded, replaced, and publication-race clients safely.

Preserve the direct *http.Client path, redirect protection, generation fencing, and idle cleanup. Include the review fixes for typed-nil transports, deterministic same-certificate publication-race coverage, and precise factory and example documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Robbie-Microsoft
Robbie-Microsoft force-pushed the robbie-microsoft-per-certificate-mtls-factory branch from 6b33d61 to 3de35ec Compare September 18, 2026 22:18
@sonarqubecloud

Copy link
Copy Markdown

Comment thread apps/confidential/confidential.go Outdated
Robbie-Microsoft and others added 5 commits October 22, 2026 10:45
Reuse the released ClientConfigurer contract for fresh certificate-scoped adapters while preserving MSAL-owned transport augmentation, cache isolation, and cleanup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge the finalized PR 661 branch while preserving the consolidated ClientConfigurer factory API and full-SHA workflow pins.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge the finalized PR 661 branch with its workflow pin removal while preserving the consolidated ClientConfigurer factory API.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge the approved MissingClientCertificate assertion update from PR 661 while preserving the consolidated ClientConfigurer factory delta.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge the finalized PR 661 workflow pins while preserving the Graph compatibility marker and consolidated ClientConfigurer factory delta.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants