auth0-api-python 1.0.0b8__tar.gz → 1.0.0b9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/PKG-INFO +88 -1
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/README.md +87 -1
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/pyproject.toml +1 -1
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/__init__.py +9 -1
- auth0_api_python-1.0.0b9/src/auth0_api_python/act.py +64 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/api_client.py +63 -3
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/config.py +4 -2
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/types.py +34 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/LICENSE +0 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/cache.py +0 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/errors.py +0 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/token_utils.py +0 -0
- {auth0_api_python-1.0.0b8 → auth0_api_python-1.0.0b9}/src/auth0_api_python/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: auth0-api-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0b9
|
|
4
4
|
Summary: SDK for verifying access tokens and securing APIs with Auth0, using Authlib.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -236,6 +236,92 @@ except ApiError as e:
|
|
|
236
236
|
|
|
237
237
|
More info: https://auth0.com/docs/authenticate/custom-token-exchange
|
|
238
238
|
|
|
239
|
+
#### On Behalf Of Token Exchange
|
|
240
|
+
|
|
241
|
+
Use `get_token_on_behalf_of()` when your API receives an `Auth0` access token for itself and needs
|
|
242
|
+
to exchange it for another `Auth0` access token targeting a downstream API while preserving the
|
|
243
|
+
same user identity. This is especially useful for `MCP` servers and other intermediary APIs that
|
|
244
|
+
need to call downstream APIs on behalf of the user.
|
|
245
|
+
|
|
246
|
+
The following example verifies the incoming access token for your API, exchanges it for a token for the downstream API, and then calls the downstream API with the exchanged token.
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
import httpx
|
|
250
|
+
|
|
251
|
+
async def handle_calendar_request(incoming_access_token: str):
|
|
252
|
+
await api_client.verify_access_token(access_token=incoming_access_token)
|
|
253
|
+
|
|
254
|
+
result = await api_client.get_token_on_behalf_of(
|
|
255
|
+
access_token=incoming_access_token,
|
|
256
|
+
audience="https://calendar-api.example.com",
|
|
257
|
+
scope="calendar:read calendar:write"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
async with httpx.AsyncClient() as client:
|
|
261
|
+
downstream_response = await client.get(
|
|
262
|
+
"https://calendar-api.example.com/events",
|
|
263
|
+
headers={"Authorization": f"Bearer {result['access_token']}"}
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
downstream_response.raise_for_status()
|
|
267
|
+
|
|
268
|
+
return downstream_response.json()
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The OBO wrapper reuses the existing RFC 8693 exchange support and fixes both token-type parameters
|
|
272
|
+
to Auth0 access-token exchange. In the current implementation, the SDK forwards the incoming access
|
|
273
|
+
token as the `subject_token` and relies on Auth0 to handle any DPoP-specific behavior for that token.
|
|
274
|
+
The OBO result only includes access-token-oriented fields. It does not expose `id_token` or
|
|
275
|
+
`refresh_token`.
|
|
276
|
+
|
|
277
|
+
#### Inspecting Delegation After Token Verification
|
|
278
|
+
|
|
279
|
+
When a downstream API or `MCP` server receives an access token that may have been issued through
|
|
280
|
+
delegation, it can verify the token first and then inspect the `act` claim to identify the current
|
|
281
|
+
actor for authorization and the full delegation chain for logging or audit.
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
import logging
|
|
285
|
+
|
|
286
|
+
from auth0_api_python import (
|
|
287
|
+
ApiClient,
|
|
288
|
+
ApiClientOptions,
|
|
289
|
+
get_current_actor,
|
|
290
|
+
get_delegation_chain,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
logger = logging.getLogger(__name__)
|
|
294
|
+
|
|
295
|
+
api_client = ApiClient(ApiClientOptions(
|
|
296
|
+
domain="<AUTH0_DOMAIN>",
|
|
297
|
+
audience="<AUTH0_AUDIENCE>",
|
|
298
|
+
))
|
|
299
|
+
|
|
300
|
+
async def authorize_delegated_request(access_token: str):
|
|
301
|
+
claims = await api_client.verify_access_token(access_token=access_token)
|
|
302
|
+
|
|
303
|
+
current_actor = get_current_actor(claims)
|
|
304
|
+
delegation_chain = get_delegation_chain(claims)
|
|
305
|
+
|
|
306
|
+
if current_actor != "mcp_server_client_id":
|
|
307
|
+
raise PermissionError("unexpected actor")
|
|
308
|
+
|
|
309
|
+
logger.info(
|
|
310
|
+
"delegated request",
|
|
311
|
+
extra={
|
|
312
|
+
"user_sub": claims["sub"],
|
|
313
|
+
"current_actor": current_actor,
|
|
314
|
+
"delegation_chain": delegation_chain,
|
|
315
|
+
},
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
return claims
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Only the outermost `act.sub` represents the current actor and should be used for authorization
|
|
322
|
+
decisions. Nested `act` values represent prior actors in the delegation chain and are better suited
|
|
323
|
+
for logging, audit, or attribution.
|
|
324
|
+
|
|
239
325
|
#### Requiring Additional Claims
|
|
240
326
|
|
|
241
327
|
If your application demands extra claims, specify them with `required_claims`:
|
|
@@ -378,3 +464,4 @@ Please do not report security vulnerabilities on the public GitHub issue tracker
|
|
|
378
464
|
<p align="center">
|
|
379
465
|
This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-api-python/LICENSE"> LICENSE</a> file for more info.
|
|
380
466
|
</p>
|
|
467
|
+
|
|
@@ -212,6 +212,92 @@ except ApiError as e:
|
|
|
212
212
|
|
|
213
213
|
More info: https://auth0.com/docs/authenticate/custom-token-exchange
|
|
214
214
|
|
|
215
|
+
#### On Behalf Of Token Exchange
|
|
216
|
+
|
|
217
|
+
Use `get_token_on_behalf_of()` when your API receives an `Auth0` access token for itself and needs
|
|
218
|
+
to exchange it for another `Auth0` access token targeting a downstream API while preserving the
|
|
219
|
+
same user identity. This is especially useful for `MCP` servers and other intermediary APIs that
|
|
220
|
+
need to call downstream APIs on behalf of the user.
|
|
221
|
+
|
|
222
|
+
The following example verifies the incoming access token for your API, exchanges it for a token for the downstream API, and then calls the downstream API with the exchanged token.
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
import httpx
|
|
226
|
+
|
|
227
|
+
async def handle_calendar_request(incoming_access_token: str):
|
|
228
|
+
await api_client.verify_access_token(access_token=incoming_access_token)
|
|
229
|
+
|
|
230
|
+
result = await api_client.get_token_on_behalf_of(
|
|
231
|
+
access_token=incoming_access_token,
|
|
232
|
+
audience="https://calendar-api.example.com",
|
|
233
|
+
scope="calendar:read calendar:write"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
async with httpx.AsyncClient() as client:
|
|
237
|
+
downstream_response = await client.get(
|
|
238
|
+
"https://calendar-api.example.com/events",
|
|
239
|
+
headers={"Authorization": f"Bearer {result['access_token']}"}
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
downstream_response.raise_for_status()
|
|
243
|
+
|
|
244
|
+
return downstream_response.json()
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The OBO wrapper reuses the existing RFC 8693 exchange support and fixes both token-type parameters
|
|
248
|
+
to Auth0 access-token exchange. In the current implementation, the SDK forwards the incoming access
|
|
249
|
+
token as the `subject_token` and relies on Auth0 to handle any DPoP-specific behavior for that token.
|
|
250
|
+
The OBO result only includes access-token-oriented fields. It does not expose `id_token` or
|
|
251
|
+
`refresh_token`.
|
|
252
|
+
|
|
253
|
+
#### Inspecting Delegation After Token Verification
|
|
254
|
+
|
|
255
|
+
When a downstream API or `MCP` server receives an access token that may have been issued through
|
|
256
|
+
delegation, it can verify the token first and then inspect the `act` claim to identify the current
|
|
257
|
+
actor for authorization and the full delegation chain for logging or audit.
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
import logging
|
|
261
|
+
|
|
262
|
+
from auth0_api_python import (
|
|
263
|
+
ApiClient,
|
|
264
|
+
ApiClientOptions,
|
|
265
|
+
get_current_actor,
|
|
266
|
+
get_delegation_chain,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
logger = logging.getLogger(__name__)
|
|
270
|
+
|
|
271
|
+
api_client = ApiClient(ApiClientOptions(
|
|
272
|
+
domain="<AUTH0_DOMAIN>",
|
|
273
|
+
audience="<AUTH0_AUDIENCE>",
|
|
274
|
+
))
|
|
275
|
+
|
|
276
|
+
async def authorize_delegated_request(access_token: str):
|
|
277
|
+
claims = await api_client.verify_access_token(access_token=access_token)
|
|
278
|
+
|
|
279
|
+
current_actor = get_current_actor(claims)
|
|
280
|
+
delegation_chain = get_delegation_chain(claims)
|
|
281
|
+
|
|
282
|
+
if current_actor != "mcp_server_client_id":
|
|
283
|
+
raise PermissionError("unexpected actor")
|
|
284
|
+
|
|
285
|
+
logger.info(
|
|
286
|
+
"delegated request",
|
|
287
|
+
extra={
|
|
288
|
+
"user_sub": claims["sub"],
|
|
289
|
+
"current_actor": current_actor,
|
|
290
|
+
"delegation_chain": delegation_chain,
|
|
291
|
+
},
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
return claims
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Only the outermost `act.sub` represents the current actor and should be used for authorization
|
|
298
|
+
decisions. Nested `act` values represent prior actors in the delegation chain and are better suited
|
|
299
|
+
for logging, audit, or attribution.
|
|
300
|
+
|
|
215
301
|
#### Requiring Additional Claims
|
|
216
302
|
|
|
217
303
|
If your application demands extra claims, specify them with `required_claims`:
|
|
@@ -353,4 +439,4 @@ Please do not report security vulnerabilities on the public GitHub issue tracker
|
|
|
353
439
|
</p>
|
|
354
440
|
<p align="center">
|
|
355
441
|
This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-api-python/LICENSE"> LICENSE</a> file for more info.
|
|
356
|
-
</p>
|
|
442
|
+
</p>
|
|
@@ -5,6 +5,7 @@ A lightweight Python SDK for verifying Auth0-issued access tokens
|
|
|
5
5
|
in server-side APIs, using Authlib for OIDC discovery and JWKS fetching.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from .act import get_current_actor, get_delegation_chain
|
|
8
9
|
from .api_client import ApiClient
|
|
9
10
|
from .cache import CacheAdapter, InMemoryCache
|
|
10
11
|
from .config import ApiClientOptions
|
|
@@ -14,7 +15,11 @@ from .errors import (
|
|
|
14
15
|
DomainsResolverError,
|
|
15
16
|
GetTokenByExchangeProfileError,
|
|
16
17
|
)
|
|
17
|
-
from .types import
|
|
18
|
+
from .types import (
|
|
19
|
+
DomainsResolver,
|
|
20
|
+
DomainsResolverContext,
|
|
21
|
+
OnBehalfOfTokenResult,
|
|
22
|
+
)
|
|
18
23
|
|
|
19
24
|
__all__ = [
|
|
20
25
|
"ApiClient",
|
|
@@ -26,5 +31,8 @@ __all__ = [
|
|
|
26
31
|
"DomainsResolverContext",
|
|
27
32
|
"DomainsResolverError",
|
|
28
33
|
"GetTokenByExchangeProfileError",
|
|
34
|
+
"get_current_actor",
|
|
35
|
+
"get_delegation_chain",
|
|
29
36
|
"InMemoryCache",
|
|
37
|
+
"OnBehalfOfTokenResult",
|
|
30
38
|
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helpers for working with the `act` claim on verified access token claims.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
|
|
8
|
+
from .errors import VerifyAccessTokenError
|
|
9
|
+
|
|
10
|
+
INVALID_ACT_CLAIM_MESSAGE = "Invalid act claim"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_current_actor(claims: Mapping[str, Any]) -> Optional[str]:
|
|
14
|
+
"""
|
|
15
|
+
Return the current actor from the outermost `act.sub`, if present.
|
|
16
|
+
|
|
17
|
+
Only the outermost `act.sub` should be used for authorization decisions.
|
|
18
|
+
Nested `act` values represent prior actors and are informational.
|
|
19
|
+
"""
|
|
20
|
+
if not isinstance(claims, Mapping):
|
|
21
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
22
|
+
|
|
23
|
+
act_claim = claims.get("act")
|
|
24
|
+
if act_claim is None:
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
if not isinstance(act_claim, Mapping):
|
|
28
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
29
|
+
|
|
30
|
+
sub = act_claim.get("sub")
|
|
31
|
+
if not isinstance(sub, str) or not sub.strip():
|
|
32
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
33
|
+
|
|
34
|
+
return sub
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_delegation_chain(claims: Mapping[str, Any]) -> list[str]:
|
|
38
|
+
"""
|
|
39
|
+
Return the delegation chain from newest actor to oldest actor.
|
|
40
|
+
|
|
41
|
+
The first entry is the current actor (outermost `act.sub`). Later entries are
|
|
42
|
+
prior actors from nested `act` values and are typically most useful for audit
|
|
43
|
+
and attribution.
|
|
44
|
+
"""
|
|
45
|
+
if not isinstance(claims, Mapping):
|
|
46
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
47
|
+
|
|
48
|
+
current = claims.get("act")
|
|
49
|
+
if current is None:
|
|
50
|
+
return []
|
|
51
|
+
|
|
52
|
+
chain: list[str] = []
|
|
53
|
+
while current is not None:
|
|
54
|
+
if not isinstance(current, Mapping):
|
|
55
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
56
|
+
|
|
57
|
+
sub = current.get("sub")
|
|
58
|
+
if not isinstance(sub, str) or not sub.strip():
|
|
59
|
+
raise VerifyAccessTokenError(INVALID_ACT_CLAIM_MESSAGE)
|
|
60
|
+
|
|
61
|
+
chain.append(sub)
|
|
62
|
+
current = current.get("act")
|
|
63
|
+
|
|
64
|
+
return chain
|
|
@@ -21,6 +21,7 @@ from .errors import (
|
|
|
21
21
|
MissingRequiredArgumentError,
|
|
22
22
|
VerifyAccessTokenError,
|
|
23
23
|
)
|
|
24
|
+
from .types import OnBehalfOfTokenResult
|
|
24
25
|
from .utils import (
|
|
25
26
|
calculate_jwk_thumbprint,
|
|
26
27
|
fetch_jwks,
|
|
@@ -34,6 +35,7 @@ from .utils import (
|
|
|
34
35
|
|
|
35
36
|
# Token Exchange constants
|
|
36
37
|
TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange" # noqa: S105
|
|
38
|
+
OBO_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token" # noqa: S105
|
|
37
39
|
MAX_ARRAY_VALUES_PER_KEY = 20 # DoS protection for extra parameter arrays
|
|
38
40
|
|
|
39
41
|
# OAuth parameter denylist - parameters that cannot be overridden via extras
|
|
@@ -232,7 +234,7 @@ class ApiClient:
|
|
|
232
234
|
http_url: The HTTP URL (required for DPoP, also used for MCD resolver context)
|
|
233
235
|
|
|
234
236
|
Returns:
|
|
235
|
-
The decoded access token claims
|
|
237
|
+
The decoded access token claims, including `act` when present.
|
|
236
238
|
|
|
237
239
|
Raises:
|
|
238
240
|
MissingRequiredArgumentError: If required args are missing
|
|
@@ -412,7 +414,7 @@ class ApiClient:
|
|
|
412
414
|
required_claims: Optional list of additional claim names that must be present
|
|
413
415
|
|
|
414
416
|
Returns:
|
|
415
|
-
The decoded token claims if valid.
|
|
417
|
+
The decoded token claims if valid, including `act` when present.
|
|
416
418
|
|
|
417
419
|
Raises:
|
|
418
420
|
MissingRequiredArgumentError: If no token is provided.
|
|
@@ -794,7 +796,7 @@ class ApiClient:
|
|
|
794
796
|
Dictionary containing:
|
|
795
797
|
- access_token (str): The Auth0 access token
|
|
796
798
|
- expires_in (int): Token lifetime in seconds
|
|
797
|
-
- expires_at (int): Unix timestamp
|
|
799
|
+
- expires_at (int): Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in
|
|
798
800
|
- id_token (str, optional): OpenID Connect ID token
|
|
799
801
|
- refresh_token (str, optional): Refresh token
|
|
800
802
|
- scope (str, optional): Granted scopes
|
|
@@ -962,6 +964,64 @@ class ApiClient:
|
|
|
962
964
|
exc
|
|
963
965
|
)
|
|
964
966
|
|
|
967
|
+
async def get_token_on_behalf_of(
|
|
968
|
+
self,
|
|
969
|
+
access_token: str,
|
|
970
|
+
audience: str,
|
|
971
|
+
scope: Optional[str] = None,
|
|
972
|
+
) -> OnBehalfOfTokenResult:
|
|
973
|
+
"""
|
|
974
|
+
Exchange an Auth0 access token for another Auth0 access token targeting a downstream API
|
|
975
|
+
while acting on behalf of the same end user (OBO).
|
|
976
|
+
|
|
977
|
+
This is a convenience wrapper around get_token_by_exchange_profile() that fixes the
|
|
978
|
+
RFC 8693 token types for Auth0 access-token-to-access-token exchange.
|
|
979
|
+
|
|
980
|
+
Args:
|
|
981
|
+
access_token: The Auth0 access token to exchange
|
|
982
|
+
audience: Target API identifier for the exchanged access token
|
|
983
|
+
scope: Optional space-separated OAuth 2.0 scopes to request
|
|
984
|
+
|
|
985
|
+
Returns:
|
|
986
|
+
Dictionary containing:
|
|
987
|
+
- access_token (str): The exchanged Auth0 access token
|
|
988
|
+
- expires_in (int): Token lifetime in seconds
|
|
989
|
+
- expires_at (int): Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in
|
|
990
|
+
- scope (str, optional): Granted scopes
|
|
991
|
+
- token_type (str, optional): Token type (typically "Bearer")
|
|
992
|
+
- issued_token_type (str, optional): RFC 8693 issued token type identifier
|
|
993
|
+
|
|
994
|
+
Raises:
|
|
995
|
+
MissingRequiredArgumentError: If required parameters are missing
|
|
996
|
+
GetTokenByExchangeProfileError: If client credentials are not configured or validation fails
|
|
997
|
+
ApiError: If the token endpoint returns an error
|
|
998
|
+
"""
|
|
999
|
+
if not audience:
|
|
1000
|
+
raise MissingRequiredArgumentError("audience")
|
|
1001
|
+
|
|
1002
|
+
result = await self.get_token_by_exchange_profile(
|
|
1003
|
+
subject_token=access_token,
|
|
1004
|
+
subject_token_type=OBO_ACCESS_TOKEN_TYPE,
|
|
1005
|
+
audience=audience,
|
|
1006
|
+
scope=scope,
|
|
1007
|
+
requested_token_type=OBO_ACCESS_TOKEN_TYPE,
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
obo_result: OnBehalfOfTokenResult = {
|
|
1011
|
+
"access_token": result["access_token"],
|
|
1012
|
+
"expires_in": result["expires_in"],
|
|
1013
|
+
"expires_at": result["expires_at"],
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
if "scope" in result:
|
|
1017
|
+
obo_result["scope"] = result["scope"]
|
|
1018
|
+
if "token_type" in result:
|
|
1019
|
+
obo_result["token_type"] = result["token_type"]
|
|
1020
|
+
if "issued_token_type" in result:
|
|
1021
|
+
obo_result["issued_token_type"] = result["issued_token_type"]
|
|
1022
|
+
|
|
1023
|
+
return obo_result
|
|
1024
|
+
|
|
965
1025
|
# ===== Private Methods =====
|
|
966
1026
|
|
|
967
1027
|
def _apply_extra(
|
|
@@ -27,8 +27,10 @@ class ApiClientOptions:
|
|
|
27
27
|
dpop_required: Whether DPoP is required (default: False, allows both Bearer and DPoP).
|
|
28
28
|
dpop_iat_leeway: Leeway in seconds for DPoP proof iat claim (default: 30).
|
|
29
29
|
dpop_iat_offset: Maximum age in seconds for DPoP proof iat claim (default: 300).
|
|
30
|
-
client_id: Required for get_access_token_for_connection
|
|
31
|
-
|
|
30
|
+
client_id: Required for get_access_token_for_connection, get_token_by_exchange_profile,
|
|
31
|
+
and get_token_on_behalf_of.
|
|
32
|
+
client_secret: Required for get_access_token_for_connection, get_token_by_exchange_profile,
|
|
33
|
+
and get_token_on_behalf_of.
|
|
32
34
|
timeout: HTTP timeout in seconds for token endpoint requests (default: 10.0).
|
|
33
35
|
"""
|
|
34
36
|
def __init__(
|
|
@@ -6,6 +6,19 @@ from collections.abc import Awaitable, Callable
|
|
|
6
6
|
from typing import Optional, TypedDict, Union
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
class ActClaim(TypedDict, total=False):
|
|
10
|
+
"""
|
|
11
|
+
Actor claim carried by access tokens issued through delegation.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
sub: The current actor for this step of the delegation chain.
|
|
15
|
+
act: The prior actor in the delegation chain, if present.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
sub: str
|
|
19
|
+
act: "ActClaim"
|
|
20
|
+
|
|
21
|
+
|
|
9
22
|
class DomainsResolverContext(TypedDict, total=False):
|
|
10
23
|
"""
|
|
11
24
|
Context passed to domains resolver functions.
|
|
@@ -19,6 +32,27 @@ class DomainsResolverContext(TypedDict, total=False):
|
|
|
19
32
|
request_headers: Optional[dict]
|
|
20
33
|
unverified_iss: str
|
|
21
34
|
|
|
35
|
+
|
|
36
|
+
class OnBehalfOfTokenResult(TypedDict, total=False):
|
|
37
|
+
"""
|
|
38
|
+
Result returned from an On Behalf Of token exchange.
|
|
39
|
+
|
|
40
|
+
Attributes:
|
|
41
|
+
access_token: The access token issued for the downstream API.
|
|
42
|
+
expires_in: Token lifetime in seconds.
|
|
43
|
+
expires_at: Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in.
|
|
44
|
+
scope: Granted scopes, if returned by Auth0.
|
|
45
|
+
token_type: Token type, if returned by Auth0.
|
|
46
|
+
issued_token_type: RFC 8693 issued token type, if returned by Auth0.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
access_token: str
|
|
50
|
+
expires_in: int
|
|
51
|
+
expires_at: int
|
|
52
|
+
scope: str
|
|
53
|
+
token_type: str
|
|
54
|
+
issued_token_type: str
|
|
55
|
+
|
|
22
56
|
DomainsResolver = Callable[
|
|
23
57
|
[DomainsResolverContext], Union[list[str], Awaitable[list[str]]]
|
|
24
58
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|