feat(credentials): support async identity_token_provider in WorkloadIdentityCredentials - #1903
Conversation
…dentityCredentials Fixes anthropics#1901 Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
IdentityTokenProvider is widened to any Awaitable[str], but _resolve_identity_token() feeds that value to asyncio.run(), which only accepts coroutine objects. A valid provider returning an asyncio.Future or Task will therefore fail; an awaitable tied to the caller's running loop is also unsafe to run in the new thread. Could the public type be narrowed to coroutine-returning callables, or the bridge handle arbitrary awaitables and loop affinity?
…rning callables Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>
|
Good catch! Narrowed |
Problem
When using Workload Identity Federation in asynchronous applications (e.g. fetching OIDC / STS tokens via an async AWS client), callers cannot pass an asynchronous
identity_token_providerfunction toWorkloadIdentityCredentials. Invoking an async callable returns an unawaited coroutine object, causingSecretStrto fail withAttributeError: 'coroutine' object has no attribute 'encode'.Root Cause
WorkloadIdentityCredentials.__call__calledself._identity_token_provider()synchronously and passed the return value directly toSecretStr().IdentityTokenProviderwas typed strictly asCallable[[], str], with no resolution logic for awaitables/coroutines.Fix
IdentityTokenProvidertype alias toUnion[Callable[[], str], Callable[[], Awaitable[str]]]._resolve_identity_tokenhelper to resolve and await asynchronous token provider callables safely, whether invoked outside or within an active running event loop._resolve_identity_tokeninsideWorkloadIdentityCredentials.__call__before wrapping the assertion intoSecretStr.Testing
Added unit test in
tests/lib/test_credentials.py::TestWorkloadIdentityCredentials::test_exchange_with_async_identity_token_providerverifying token exchange with an async identity token provider. Verified with pytest.