@@ -406,6 +406,57 @@ def token() -> oauth.Token:
406406
407407 return OAuthCredentialsProvider (refreshed_headers , token )
408408
409+ @oauth_credentials_strategy ("azdo-oidc" , ["host" , "client_id" ])
410+ def azure_devops_oidc (cfg : "Config" ) -> Optional [CredentialsProvider ]:
411+ """
412+ Azure DevOps OIDC authentication uses a Token Supplier to get a JWT Token
413+ and exchanges it for a Databricks Token.
414+
415+ Supported in Azure DevOps pipelines with OIDC service connections.
416+ """
417+ supplier = oidc_token_supplier .AzureDevOpsOIDCTokenSupplier ()
418+
419+ audience = cfg .token_audience
420+ if audience is None and cfg .is_account_client :
421+ audience = cfg .account_id
422+ if audience is None and not cfg .is_account_client :
423+ audience = cfg .oidc_endpoints .token_endpoint
424+
425+ # Try to get an idToken. If no supplier returns a token, we cannot use this authentication mode.
426+ id_token = supplier .get_oidc_token (audience )
427+ if not id_token :
428+ return None
429+
430+ def token_source_for (audience : str ) -> oauth .TokenSource :
431+ id_token = supplier .get_oidc_token (audience )
432+ if not id_token :
433+ # Should not happen, since we checked it above.
434+ raise Exception ("Cannot get Azure DevOps OIDC token" )
435+
436+ return oauth .ClientCredentials (
437+ client_id = cfg .client_id ,
438+ client_secret = "" , # we have no (rotatable) secrets in OIDC flow
439+ token_url = cfg .oidc_endpoints .token_endpoint ,
440+ endpoint_params = {
441+ "subject_token_type" : "urn:ietf:params:oauth:token-type:jwt" ,
442+ "subject_token" : id_token ,
443+ "grant_type" : "urn:ietf:params:oauth:grant-type:token-exchange" ,
444+ },
445+ scopes = ["all-apis" ],
446+ use_params = True ,
447+ disable_async = cfg .disable_async_token_refresh ,
448+ )
449+
450+ def refreshed_headers () -> Dict [str , str ]:
451+ token = token_source_for (audience ).token ()
452+ return {"Authorization" : f"{ token .token_type } { token .access_token } " }
453+
454+ def token () -> oauth .Token :
455+ return token_source_for (audience ).token ()
456+
457+ return OAuthCredentialsProvider (refreshed_headers , token )
458+
459+
409460
410461@oauth_credentials_strategy ("github-oidc-azure" , ["host" , "azure_client_id" ])
411462def github_oidc_azure (cfg : "Config" ) -> Optional [CredentialsProvider ]:
@@ -1015,6 +1066,7 @@ def __init__(self) -> None:
10151066 env_oidc ,
10161067 file_oidc ,
10171068 github_oidc ,
1069+ azure_devops_oidc ,
10181070 azure_service_principal ,
10191071 github_oidc_azure ,
10201072 azure_cli ,
0 commit comments