@@ -522,3 +522,65 @@ class Pipeline:
522
522
return first_node.send(pipeline_request) # type: ignore
523
523
524
524
```
525
+
526
+ ## Credentials
527
+
528
+ ### TokenCredential protocol
529
+
530
+ Clients from the Azure SDK often require a ` TokenCredential ` instance in their constructors. A ` TokenCredential ` is
531
+ meant to provide OAuth tokens to authenticate service requests and can be implemented in a number of ways.
532
+
533
+ The ` TokenCredential ` protocol specifies a class that has a single method -- ` get_token ` -- which returns an
534
+ ` AccessToken ` : a ` NamedTuple ` containing a ` token ` string and an ` expires_on ` integer (in Unix time).
535
+
536
+ ``` python
537
+ AccessToken = NamedTuple(" AccessToken" , [(" token" , str ), (" expires_on" , int )])
538
+
539
+ class TokenCredential (Protocol ):
540
+ """ Protocol for classes able to provide OAuth tokens."""
541
+
542
+ def get_token (
543
+ self , * scopes : str , claims : Optional[str ] = None , tenant_id : Optional[str ] = None , ** kwargs : Any
544
+ ) -> AccessToken:
545
+ """ Request an access token for `scopes`.
546
+
547
+ :param str scopes: The type(s) of access needed.
548
+
549
+ :keyword str claims: Additional claims required in the token, such as those returned in a resource
550
+ provider's claims challenge following an authorization failure.
551
+ :keyword str tenant_id: Optional tenant to include in the token request.
552
+
553
+ :rtype: AccessToken
554
+ :return: An AccessToken instance containing the token string and its expiration time in Unix time.
555
+ """
556
+ ```
557
+
558
+ A ` TokenCredential ` implementation needs to implement the ` get_token ` method to these specifications and can optionally
559
+ implement additional methods. The [ ` azure-identity ` ] [ identity_github ] package has a number of ` TokenCredential `
560
+ implementations that can be used for reference. For example, the [ ` InteractiveCredential ` ] [ interactive_cred ] is used as
561
+ a base class for multiple credentials and uses ` claims ` and ` tenant_id ` in token requests.
562
+
563
+ There is also an async protocol -- the ` AsyncTokenCredential ` protocol -- that specifies a class with an aysnc
564
+ ` get_token ` method with the same arguments. An ` AsyncTokenCredential ` implementation additionally needs to be a context
565
+ manager, with ` __aenter__ ` , ` __aexit__ ` , and ` close ` methods.
566
+
567
+ #### Known uses of ` get_token ` keyword-only parameters
568
+
569
+ ** ` claims ` **
570
+
571
+ | Service/Feature | Reason |
572
+ | --- | --- |
573
+ | [ Continuous Access Evaluation] [ cae_doc ] | Respond to claim challenges when unexpired tokens have access revoked
574
+
575
+ ** ` tenant_id ` **
576
+
577
+ | Service/Feature | Reason |
578
+ | --- | --- |
579
+ | Key Vault ([ example] [ kv_tenant_id ] ) | Request access in a tenant that was discovered as part of an authentication challenge
580
+
581
+
582
+ [ cae_doc ] : https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation
583
+ [ custom_creds_sample ] : https://github.com/Azure/azure-sdk-for-python/blob/fc95f8d3d84d076ffea158116ca1bf6912689c70/sdk/identity/azure-identity/samples/custom_credentials.py
584
+ [ identity_github ] : https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity
585
+ [ interactive_cred ] : https://github.com/Azure/azure-sdk-for-python/blob/58c974883123b10b1ca9249ac49109220facb02f/sdk/identity/azure-identity/azure/identity/_internal/interactive.py
586
+ [ kv_tenant_id ] : https://github.com/Azure/azure-sdk-for-python/blob/0a0cc97f178a7476ec79f29c090b8c93ad5d4955/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/challenge_auth_policy.py#L102
0 commit comments