Skip to content

Commit 513d3f9

Browse files
committed
Resolve TokenAudience from host metadata for account hosts
Port of Go SDK #1543. When resolveHostMetadata() runs on an account host and tokenAudience is not already set, automatically sets it to the accountId. This enables OIDC token exchange to work correctly for account-level operations without explicit TOKEN_AUDIENCE config. Co-authored-by: Isaac
1 parent f5a4892 commit 513d3f9

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

databricks-sdk-java/src/main/java/com/databricks/sdk/core/DatabricksConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,10 @@ void resolveHostMetadata() throws IOException {
898898
discoveryUrl = oidcUri.resolve(".well-known/oauth-authorization-server").toString();
899899
LOG.debug("Resolved discovery_url from host metadata: \"{}\"", discoveryUrl);
900900
}
901+
// For account hosts, use the accountId as the token audience if not already set.
902+
if (tokenAudience == null && getClientType() == ClientType.ACCOUNT && accountId != null) {
903+
tokenAudience = accountId;
904+
}
901905
}
902906

903907
private OpenIDConnectEndpoints fetchOidcEndpointsFromDiscovery() {

databricks-sdk-java/src/test/java/com/databricks/sdk/core/DatabricksConfigTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,52 @@ public void testResolveHostMetadataRaisesOnHttpError() throws IOException {
586586
}
587587
}
588588

589+
@Test
590+
public void testResolveHostMetadataSetsTokenAudienceForAccountHost() throws IOException {
591+
// For a unified host with no workspaceId (ACCOUNT client type), resolveHostMetadata should
592+
// set tokenAudience to accountId when not already configured.
593+
String response =
594+
"{\"oidc_endpoint\":\"https://acc.databricks.com/oidc/accounts/{account_id}\","
595+
+ "\"account_id\":\""
596+
+ DUMMY_ACCOUNT_ID
597+
+ "\"}";
598+
try (FixtureServer server =
599+
new FixtureServer()
600+
.with("GET", "/.well-known/databricks-config", response, 200)
601+
.with("GET", "/.well-known/databricks-config", response, 200)) {
602+
DatabricksConfig config =
603+
new DatabricksConfig()
604+
.setHost(server.getUrl())
605+
.setExperimentalIsUnifiedHost(true)
606+
.setAccountId(DUMMY_ACCOUNT_ID);
607+
config.resolve(emptyEnv());
608+
// Client type should be ACCOUNT (unified host, no workspaceId)
609+
assertEquals(ClientType.ACCOUNT, config.getClientType());
610+
config.resolveHostMetadata();
611+
assertEquals(DUMMY_ACCOUNT_ID, config.getTokenAudience());
612+
}
613+
}
614+
615+
@Test
616+
public void testResolveHostMetadataDoesNotOverwriteTokenAudience() throws IOException {
617+
String response =
618+
"{\"oidc_endpoint\":\"https://acc.databricks.com/oidc/accounts/{account_id}\","
619+
+ "\"account_id\":\""
620+
+ DUMMY_ACCOUNT_ID
621+
+ "\"}";
622+
try (FixtureServer server =
623+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
624+
DatabricksConfig config =
625+
new DatabricksConfig()
626+
.setHost(server.getUrl())
627+
.setAccountId(DUMMY_ACCOUNT_ID)
628+
.setTokenAudience("custom-audience");
629+
config.resolve(emptyEnv());
630+
config.resolveHostMetadata();
631+
assertEquals("custom-audience", config.getTokenAudience());
632+
}
633+
}
634+
589635
// --- tryResolveHostMetadata (config init) tests ---
590636

591637
@Test

0 commit comments

Comments
 (0)