Skip to content

Conversation

@Divyansh-db
Copy link
Contributor

@Divyansh-db Divyansh-db commented Aug 14, 2025

Added native support for Azure DevOps OIDC authentication to allow authentication from Azure DevOps pipeline's environment.

Testing

Tested on an Azure DevOps project. Used the SDK to authenticate with a Databrick's workspace using Azure DevOps OIDC

  1. Created a demo python files that uses the SDK to create a Workspace Client: This will test if the OIDC authentication is working
Screenshot 2025-09-18 at 15 42 18
  1. Created a pipeline to run the demo file. Set the necessary environment variables.
    (System.AccessToken is slightly different, it needs to be exported through pipeline syntax: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken)
Screenshot 2025-09-18 at 15 43 34
  1. The pipeline runs successfully indicating that authentication succeeded.
Screenshot 2025-09-18 at 15 43 59

@functools.wraps(func)
def wrapper(cfg: "Config") -> Optional[CredentialsProvider]:
for attr in require:
getattr(cfg, attr)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seemed like unnecessary Double check

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure? what does this function do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function checks if the attribute exists in the config or not. This check is redundant, as it is done in the next line as well



class DefaultCredentials:
"""Select the first applicable credential provider from the chain"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Strategy seems to be the correct word as we are trying different auth strategies until one suceeds

Copy link
Contributor

Choose a reason for hiding this comment

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

I remember discussing this a while ago and the decision was that provider was better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I came after working in go SDK. It was named strategy there, therefore made the change here. But if this was already discussed then I will revert back to provider.

@Divyansh-db Divyansh-db force-pushed the divyansh-vijayvergia_data/Azure_DevOps_OIDC branch from 3e353da to 5bbb16b Compare September 18, 2025 13:39
@Divyansh-db Divyansh-db changed the title added Azure DevOps OIDC authentication support [DECO-25297] Add native support for Azure DevOps OIDC authentication Sep 18, 2025
@functools.wraps(func)
def wrapper(cfg: "Config") -> Optional[CredentialsProvider]:
for attr in require:
getattr(cfg, attr)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure? what does this function do?

Supported in Azure DevOps pipelines with OIDC service connections.
"""
try:
supplier = oidc_token_supplier.AzureDevOpsOIDCTokenSupplier()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed? GitHubOIDCTokenSupplier does raise an exception, and therefore there is no try/catch. Is this different for a reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same. For early exit.

audience = cfg.oidc_endpoints.token_endpoint

# Try to get an idToken. If no supplier returns a token, we cannot use this authentication mode.
id_token = supplier.get_oidc_token(audience)
Copy link
Contributor

Choose a reason for hiding this comment

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

This function is almost the same as github_oidc. Can and should we reuse the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The old code should not be changed, right? The common part is within the GithubOIDC function. I can refactor the code to put the common parts outside it and use them in AzureDevOps. What is the better option?

Copy link
Contributor

Choose a reason for hiding this comment

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

On a quick look, I think that the only difference if the supplier being used.
We may be able to have

#TODO: better name
def _internal_oidc(cfg: "Config", supplier: ) -> Optional[CredentialsProvider]:
...

@oauth_credentials_strategy("azure-devops-oidc", ["host", "client_id"])
def azure_devops_oidc(cfg: "Config") -> Optional[CredentialsProvider]:
    return _internal_oidc(cfg, () -> oidc_token_supplier.AzureDevOpsOIDCTokenSupplier())

return None

return response_json["value"]

Copy link
Contributor

Choose a reason for hiding this comment

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

Same: GitHubOIDC does not validate on create. Is there a reasons to change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done to ensure Early exit. This is similar to what is done in Go SDK. If the environment variables are not set then we are sure that we are not in Azure DevOps Environment so we should exit at the earliest and try other providers.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we add a TODO on the GitHub OIDC implementation to make it clear that it is the one with tech debt?

Copy link
Contributor

@hectorcast-db hectorcast-db left a comment

Choose a reason for hiding this comment

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

LGTM. Also get Parth approval.

Supported in GitHub Actions with OIDC service connections.
"""
return _oidc_credentials_provider(
cfg=cfg, supplier_factory=lambda: oidc_token_supplier.GitHubOIDCTokenSupplier(), provider_name="GitHub OIDC"
Copy link
Contributor

Choose a reason for hiding this comment

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

This will tell the formatter to have one argument per line (like you do below).

Suggested change
cfg=cfg, supplier_factory=lambda: oidc_token_supplier.GitHubOIDCTokenSupplier(), provider_name="GitHub OIDC"
cfg=cfg, supplier_factory=lambda: oidc_token_supplier.GitHubOIDCTokenSupplier(), provider_name="GitHub OIDC",

return None

return response_json["value"]

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we add a TODO on the GitHub OIDC implementation to make it clear that it is the one with tech debt?

@github-actions
Copy link

github-actions bot commented Oct 1, 2025

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/sdk-py

Inputs:

  • PR number: 1027
  • Commit SHA: ac5db4f4c619ff76e8fd2d6f699fda15cb70e483

Checks will be approved automatically on success.

@Divyansh-db Divyansh-db added this pull request to the merge queue Oct 1, 2025
Merged via the queue into main with commit 88f1047 Oct 1, 2025
17 checks passed
@Divyansh-db Divyansh-db deleted the divyansh-vijayvergia_data/Azure_DevOps_OIDC branch October 1, 2025 17:35
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.

5 participants