-
Notifications
You must be signed in to change notification settings - Fork 50
Add support to authenticate with Account-wide token federation #1219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,49 @@ | ||
package config | ||
package oidc | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/url" | ||
|
||
"github.com/databricks/databricks-sdk-go/config/experimental/auth" | ||
"github.com/databricks/databricks-sdk-go/config/experimental/auth/oidc" | ||
"github.com/databricks/databricks-sdk-go/credentials/u2m" | ||
"github.com/databricks/databricks-sdk-go/logger" | ||
"golang.org/x/oauth2" | ||
"golang.org/x/oauth2/clientcredentials" | ||
) | ||
|
||
// Creates a new Databricks OIDC TokenSource. | ||
func NewDatabricksOIDCTokenSource(cfg DatabricksOIDCTokenSourceConfig) auth.TokenSource { | ||
return &databricksOIDCTokenSource{ | ||
cfg: cfg, | ||
} | ||
} | ||
|
||
// Config for Databricks OIDC TokenSource. | ||
// DatabricksOIDCTokenSourceConfig is the configuration for a Databricks OIDC | ||
// TokenSource. | ||
type DatabricksOIDCTokenSourceConfig struct { | ||
// ClientID is the client ID of the Databricks OIDC application. For | ||
// Databricks Service Principal, this is the Application ID of the Service Principal. | ||
// ClientID of the Databricks OIDC application. It corresponds to the | ||
// Application ID of the Databricks Service Principal. | ||
// | ||
// This field is only required for Workload Identity Federation and should | ||
// be empty for Account-wide token federation. | ||
ClientID string | ||
// [Optional] AccountID is the account ID of the Databricks Account. | ||
// This is only used for Account level tokens. | ||
|
||
// AccountID is the account ID of the Databricks Account. This field is | ||
// only required for Account-wide token federation. | ||
AccountID string | ||
|
||
// Host is the host of the Databricks account or workspace. | ||
Host string | ||
// TokenEndpointProvider returns the token endpoint for the Databricks OIDC application. | ||
|
||
// TokenEndpointProvider returns the token endpoint for the Databricks OIDC | ||
// application. | ||
TokenEndpointProvider func(ctx context.Context) (*u2m.OAuthAuthorizationServer, error) | ||
|
||
// Audience is the audience of the Databricks OIDC application. | ||
// This is only used for Workspace level tokens. | ||
Audience string | ||
// IdTokenSource returns the IDToken to be used for the token exchange. | ||
IdTokenSource oidc.IDTokenSource | ||
|
||
// IDTokenSource returns the IDToken to be used for the token exchange. | ||
IDTokenSource IDTokenSource | ||
} | ||
|
||
// NewDatabricksOIDCTokenSource returns a new Databricks OIDC TokenSource. | ||
func NewDatabricksOIDCTokenSource(cfg DatabricksOIDCTokenSourceConfig) auth.TokenSource { | ||
return &databricksOIDCTokenSource{cfg: cfg} | ||
} | ||
|
||
// databricksOIDCTokenSource is a auth.TokenSource which exchanges a token using | ||
|
@@ -47,10 +54,6 @@ type databricksOIDCTokenSource struct { | |
|
||
// Token implements [TokenSource.Token] | ||
func (w *databricksOIDCTokenSource) Token(ctx context.Context) (*oauth2.Token, error) { | ||
if w.cfg.ClientID == "" { | ||
logger.Debugf(ctx, "Missing ClientID") | ||
return nil, errors.New("missing ClientID") | ||
} | ||
if w.cfg.Host == "" { | ||
logger.Debugf(ctx, "Missing Host") | ||
return nil, errors.New("missing Host") | ||
|
@@ -59,8 +62,17 @@ func (w *databricksOIDCTokenSource) Token(ctx context.Context) (*oauth2.Token, e | |
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if w.cfg.ClientID == "" { | ||
logger.Debugf(ctx, "No ClientID provided, authenticating with Account-wide token federation") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is more of a question than a comment: Should account-wide token federation also be added to the Java SDK? Currently, ClientID is not an optional field in the Java SDK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question! Yes, we will have to add that in the Java SDK too. |
||
} else { | ||
logger.Debugf(ctx, "Client ID provided, authenticating with Workload Identity Federation") | ||
} | ||
|
||
// TODO: The audience is a concept of the IDToken that should likely be | ||
// configured when the IDTokenSource is created. | ||
audience := w.determineAudience(endpoints) | ||
idToken, err := w.cfg.IdTokenSource.IDToken(ctx, audience) | ||
idToken, err := w.cfg.IDTokenSource.IDToken(ctx, audience) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we document what is
env-oidc
andfile-oidc
somewhere?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not outside of the code as far as I can tell. Though, there is an ongoing effort to document these centrally.