Cache OBO credentials on AzureProvider for token reuse (#3212)

* Cache OBO credentials on AzureProvider for token reuse

* chore: Update SDK documentation

* Close evicted OBO credentials properly

* chore: Update SDK documentation

---------

Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
Jeremiah Lowin 2026-02-18 11:43:36 -05:00 committed by GitHub
commit 7aba0df323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 173 additions and 39 deletions

View file

@ -14,7 +14,7 @@ using the OAuth Proxy pattern for non-DCR OAuth flows.
## Functions
### `EntraOBOToken` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L658" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `EntraOBOToken` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L680" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
EntraOBOToken(scopes: list[str]) -> str
@ -43,7 +43,7 @@ or OBO exchange fails
## Classes
### `AzureProvider` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L31" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `AzureProvider` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L33" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Azure (Microsoft Entra) OAuth provider for FastMCP.
@ -78,7 +78,7 @@ Setup:
**Methods:**
#### `authorize` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L235" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `authorize` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L243" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@ -98,17 +98,17 @@ scopes to determine the resource/audience instead of a separate parameter.
- Authorization URL to redirect the user to Azure AD
#### `create_obo_credential` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L461" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `get_obo_credential` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L469" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
create_obo_credential(self, user_assertion: str) -> OnBehalfOfCredential
get_obo_credential(self, user_assertion: str) -> OnBehalfOfCredential
```
Create an OnBehalfOfCredential for OBO token exchange.
Get a cached or new OnBehalfOfCredential for OBO token exchange.
Uses the AzureProvider's configuration (client_id, client_secret,
tenant_id, authority) to create a credential that can exchange the
user's token for downstream API tokens.
Credentials are cached by user assertion so the Azure SDK's internal
token cache can avoid redundant OBO exchanges when the same user
calls multiple tools with the same scopes.
**Args:**
- `user_assertion`: The user's access token to exchange via OBO.
@ -120,7 +120,16 @@ user's token for downstream API tokens.
- `ImportError`: If azure-identity is not installed (requires fastmcp[azure]).
### `AzureJWTVerifier` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L489" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `close_obo_credentials` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L510" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
close_obo_credentials(self) -> None
```
Close all cached OBO credentials.
### `AzureJWTVerifier` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L521" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
JWT verifier pre-configured for Azure AD / Microsoft Entra ID.
@ -157,7 +166,7 @@ Example::
**Methods:**
#### `scopes_supported` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L569" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `scopes_supported` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/auth/providers/azure.py#L601" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
scopes_supported(self) -> list[str]