Skip to content

feat(credentials): support async identity_token_provider in WorkloadIdentityCredentials - #1903

Open
lx3133584 wants to merge 2 commits into
anthropics:mainfrom
lx3133584:feat/workload-identity-async-token-provider
Open

feat(credentials): support async identity_token_provider in WorkloadIdentityCredentials#1903
lx3133584 wants to merge 2 commits into
anthropics:mainfrom
lx3133584:feat/workload-identity-async-token-provider

Conversation

@lx3133584

Copy link
Copy Markdown

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_provider function to WorkloadIdentityCredentials. Invoking an async callable returns an unawaited coroutine object, causing SecretStr to fail with AttributeError: 'coroutine' object has no attribute 'encode'.

Root Cause

WorkloadIdentityCredentials.__call__ called self._identity_token_provider() synchronously and passed the return value directly to SecretStr(). IdentityTokenProvider was typed strictly as Callable[[], str], with no resolution logic for awaitables/coroutines.

Fix

  1. Broaden IdentityTokenProvider type alias to Union[Callable[[], str], Callable[[], Awaitable[str]]].
  2. Add _resolve_identity_token helper to resolve and await asynchronous token provider callables safely, whether invoked outside or within an active running event loop.
  3. Call _resolve_identity_token inside WorkloadIdentityCredentials.__call__ before wrapping the assertion into SecretStr.

Testing

Added unit test in tests/lib/test_credentials.py::TestWorkloadIdentityCredentials::test_exchange_with_async_identity_token_provider verifying token exchange with an async identity token provider. Verified with pytest.

…dentityCredentials

Fixes anthropics#1901

Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>
@lx3133584
lx3133584 requested a review from a team as a code owner September 1, 2026 09:52

@sylvesterkaczmarek sylvesterkaczmarek left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@lx3133584

Copy link
Copy Markdown
Author

Good catch! Narrowed IdentityTokenProvider to Union[Callable[[], str], Callable[[], Coroutine[Any, Any, str]]] and updated the runtime check to inspect.iscoroutine(). This makes the callable contract explicit for async def providers and avoids issues with arbitrary Future/Task objects tied to different event loops.

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