[Feature Request] Client assertion should accept a callback function
MSAL client type
Confidential
Problem Statement
When client_credential is set to client_assertion, the only acceptable value is a token. However, tokens have a definite validity and as a result, the library as is it not suitable when using dynamic tokens - such as when using workload identities in AKS - because at some point the token becomes expired and a new instance of the Confidential client has to be initiated, which is not straightforward.
Proposed solution
I propose that client_assertion should accept a callback function which is evaluated on demand by the MSAL library, allowing the user-supplied function to retrieve a custom token.
This feature is already available in the .NET and JS versions of this library.
Guess what? Since day 1, MSAL Python has an undocumented feature of accepting this:
def assertion_callback():
return "dynamically obtain your new assertion here"
app = ConfidentialClientApplication(
...,
client_credential={"client_assertion": assertion_callback},
)
Note that the callback will be called whenever a token request needs to be sent on the wire. That means:
- If you are acquiring the same token (via
acquire_token_for_client(..., scopes=["same", "scopes"])or viaacquire_token_silent(...)), MSAL Python's token cache will automatically kick in, no new token request will be made, and your callback won't be called, which is good for efficiency. - If you are acquiring a new token (via
acquire_token_for_client(..., scopes=["different", "scopes"]), or viaacquire_token_on_behalf_of("a new user assertion", ...)), your callback will be frequently called. But lucky that MSAL Python also has an internal helperAutoRefresher.from msal import AutoRefresher # NOT YET available, but we can expose it in our next release smart_callback = AutoRefresher(assertion_callback, expires_in=3600) app = ConfidentialClientApplication( ..., client_credential={"client_assertion": smart_callback}, )
Cool, can you please (soft) deprecate the string variant then and ensure the docs are updated?
It just causes confusion and there is really no scenario where a string should be provided, because the string assertion expires.