Task type
Development
Description
Refactor the mTLS flows so that the client assertion provider delegate is invoked only once, at the TokenClient level, instead of performing a double callback and cross-request caching. Currently the signed assertion provider is called both in MtlsPopParametersInitializer to extract the certificate and again by CredentialMaterialResolver during actual credential resolution. This creates risk of mismatched assertions/certificates, and overly complicates the flow by requiring properties for caching the result across objects.
Instead, design the flow so that TokenClient calls the provider once, extracts both the assertion and the certificate, and initializes credential setup and mTLS bindings from this result directly. Preflight initializers only validate that mTLS requirements are set, but do not need to call the provider or extract the cert. The assertion and certificate should be sourced together at the last responsible point by TokenClient, enforcing a single provider invocation per flow.
Solution
- Move the assertion provider invocation responsibility to TokenClient, so it is only called once.
- TokenClient should extract both the assertion and TokenBindingCertificate in one call.
- Use the assertion and cert for credential/material setup directly from this result.
- Adjust MtlsPopParametersInitializer (and related preflight paths) to no longer perform provider invocations or cache assertion results – just validate mTLS requirements as needed.
- Remove CachedClientSignedAssertion properties from parameters/context.
- Add/adjust unit tests to verify the provider delegate is called exactly once end-to-end, even in mTLS cases.
Task type
Development
Description
Refactor the mTLS flows so that the client assertion provider delegate is invoked only once, at the TokenClient level, instead of performing a double callback and cross-request caching. Currently the signed assertion provider is called both in MtlsPopParametersInitializer to extract the certificate and again by CredentialMaterialResolver during actual credential resolution. This creates risk of mismatched assertions/certificates, and overly complicates the flow by requiring properties for caching the result across objects.
Instead, design the flow so that TokenClient calls the provider once, extracts both the assertion and the certificate, and initializes credential setup and mTLS bindings from this result directly. Preflight initializers only validate that mTLS requirements are set, but do not need to call the provider or extract the cert. The assertion and certificate should be sourced together at the last responsible point by TokenClient, enforcing a single provider invocation per flow.
Solution