SpyBara
Go Premium

Documentation 2026-07-16 17:00 UTC to 2026-07-17 19:58 UTC

10 files changed +160 −201. View all changes and history on the product overview
2026
Sat 18 22:00 Fri 17 19:58 Thu 16 17:00 Wed 15 16:58 Tue 14 21:58 Mon 13 21:58 Sat 11 07:01 Fri 10 23:02 Thu 9 17:03 Wed 8 22:02 Mon 6 22:58 Sat 4 16:59
Details

68import com.openai.client.OpenAIClient;68import com.openai.client.OpenAIClient;

69import com.openai.client.okhttp.OpenAIOkHttpClient;69import com.openai.client.okhttp.OpenAIOkHttpClient;

70 70 

71OpenAIClient client = OpenAIOkHttpClient.builder()71OpenAIClient client =

72 .adminApiKey(System.getenv("OPENAI_ADMIN_KEY"))72 OpenAIOkHttpClient.builder().adminApiKey(System.getenv("OPENAI_ADMIN_KEY")).build();

73 .build();

74```73```

75 74 

76 75 


133import com.openai.models.admin.organization.projects.modelpermissions.ProjectModelPermissions;132import com.openai.models.admin.organization.projects.modelpermissions.ProjectModelPermissions;

134import java.util.List;133import java.util.List;

135 134 

136ProjectModelPermissions modelPermissions = client.admin()135ProjectModelPermissions modelPermissions =

136 client

137 .admin()

137 .organization()138 .organization()

138 .projects()139 .projects()

139 .modelPermissions()140 .modelPermissions()


142 ModelPermissionUpdateParams.builder()143 ModelPermissionUpdateParams.builder()

143 .mode(ModelPermissionUpdateParams.Mode.ALLOW_LIST)144 .mode(ModelPermissionUpdateParams.Mode.ALLOW_LIST)

144 .modelIds(List.of("gpt-4.1", "o3"))145 .modelIds(List.of("gpt-4.1", "o3"))

145 .build()146 .build());

146 );

147 147 

148System.out.println(modelPermissions.mode());148System.out.println(modelPermissions.mode());

149```149```


231import com.openai.models.admin.organization.projects.spendalerts.ProjectSpendAlert;231import com.openai.models.admin.organization.projects.spendalerts.ProjectSpendAlert;

232import com.openai.models.admin.organization.projects.spendalerts.SpendAlertCreateParams;232import com.openai.models.admin.organization.projects.spendalerts.SpendAlertCreateParams;

233 233 

234ProjectSpendAlert spendAlert = client.admin()234ProjectSpendAlert spendAlert =

235 client

236 .admin()

235 .organization()237 .organization()

236 .projects()238 .projects()

237 .spendAlerts()239 .spendAlerts()


244 SpendAlertCreateParams.NotificationChannel.builder()246 SpendAlertCreateParams.NotificationChannel.builder()

245 .addRecipient("billing@example.com")247 .addRecipient("billing@example.com")

246 .subjectPrefix("[OpenAI spend]")248 .subjectPrefix("[OpenAI spend]")

247 .build()249 .build())

248 )

249 .thresholdAmount(50000L)250 .thresholdAmount(50000L)

250 .build()251 .build());

251 );

252 252 

253System.out.println(spendAlert.id());253System.out.println(spendAlert.id());

254```254```


308import com.openai.models.admin.organization.projects.dataretention.DataRetentionUpdateParams;308import com.openai.models.admin.organization.projects.dataretention.DataRetentionUpdateParams;

309import com.openai.models.admin.organization.projects.dataretention.ProjectDataRetention;309import com.openai.models.admin.organization.projects.dataretention.ProjectDataRetention;

310 310 

311ProjectDataRetention dataRetention = client.admin()311ProjectDataRetention dataRetention =

312 client

313 .admin()

312 .organization()314 .organization()

313 .projects()315 .projects()

314 .dataRetention()316 .dataRetention()


316 "proj_abc",318 "proj_abc",

317 DataRetentionUpdateParams.builder()319 DataRetentionUpdateParams.builder()

318 .retentionType(DataRetentionUpdateParams.RetentionType.ORGANIZATION_DEFAULT)320 .retentionType(DataRetentionUpdateParams.RetentionType.ORGANIZATION_DEFAULT)

319 .build()321 .build());

320 );

321 322 

322System.out.println(dataRetention.type());323System.out.println(dataRetention.type());

323```324```


374import com.openai.models.admin.organization.invites.Invite;375import com.openai.models.admin.organization.invites.Invite;

375import com.openai.models.admin.organization.invites.InviteCreateParams;376import com.openai.models.admin.organization.invites.InviteCreateParams;

376 377 

377Invite invite = client.admin().organization().invites().create(378Invite invite =

379 client

380 .admin()

381 .organization()

382 .invites()

383 .create(

378 InviteCreateParams.builder()384 InviteCreateParams.builder()

379 .email("user@example.com")385 .email("user@example.com")

380 .role(InviteCreateParams.Role.READER)386 .role(InviteCreateParams.Role.READER)

381 .build()387 .build());

382);

383 388 

384System.out.println(invite.id());389System.out.println(invite.id());

385```390```


432```java437```java

433import com.openai.models.admin.organization.auditlogs.AuditLogListParams;438import com.openai.models.admin.organization.auditlogs.AuditLogListParams;

434 439 

435var page = client.admin().organization().auditLogs().list(440var page =

436 AuditLogListParams.builder()441 client

437 .limit(10L)442 .admin()

438 .build()443 .organization()

439);444 .auditLogs()

445 .list(AuditLogListParams.builder().limit(10L).build());

440 446 

441page.data().forEach(auditLog -> System.out.println(auditLog.id()));447page.data().forEach(auditLog -> System.out.println(auditLog.id()));

442```448```

Details

236- Confirm your supported model and AWS Region in Amazon Bedrock.236- Confirm your supported model and AWS Region in Amazon Bedrock.

237- Verify the exact API features your workload needs.237- Verify the exact API features your workload needs.

238- Compare Bedrock pricing and direct API pricing before launch.238- Compare Bedrock pricing and direct API pricing before launch.

239- For Codex-specific setup, see239- For setup in ChatGPT Work and Codex, see

240 [Use Codex with Amazon Bedrock](https://developers.openai.com/codex/amazon-bedrock).240 [Use ChatGPT Work and Codex with Amazon Bedrock](https://developers.openai.com/codex/amazon-bedrock).

Details

74 public static void main(String[] args) {74 public static void main(String[] args) {

75 OpenAIClient client = OpenAIOkHttpClient.fromEnv();75 OpenAIClient client = OpenAIOkHttpClient.fromEnv();

76 76 

77 ResponseCreateParams params = ResponseCreateParams.builder()77 ResponseCreateParams params =

78 .input("Say this is a test")78 ResponseCreateParams.builder().input("Say this is a test").model("gpt-5.6").build();

79 .model("gpt-5.6")

80 .build();

81 79 

82 Response response = client.responses().create(params);80 Response response = client.responses().create(params);

83 System.out.println(response.outputText());81 response.output().stream()

82 .flatMap(item -> item.message().stream())

83 .flatMap(message -> message.content().stream())

84 .flatMap(content -> content.outputText().stream())

85 .forEach(outputText -> System.out.println(outputText.text()));

84 }86 }

85}87}

86```88```

guides/text.md +7 −5

Details

72 public static void main(String[] args) {72 public static void main(String[] args) {

73 OpenAIClient client = OpenAIOkHttpClient.fromEnv();73 OpenAIClient client = OpenAIOkHttpClient.fromEnv();

74 74 

75 ResponseCreateParams params = ResponseCreateParams.builder()75 ResponseCreateParams params =

76 .input("Say this is a test")76 ResponseCreateParams.builder().input("Say this is a test").model("gpt-5.6").build();

77 .model("gpt-5.6")

78 .build();

79 77 

80 Response response = client.responses().create(params);78 Response response = client.responses().create(params);

81 System.out.println(response.outputText());79 response.output().stream()

80 .flatMap(item -> item.message().stream())

81 .flatMap(message -> message.content().stream())

82 .flatMap(content -> content.outputText().stream())

83 .forEach(outputText -> System.out.println(outputText.text()));

82 }84 }

83}85}

84```86```

Details

353import com.openai.client.okhttp.OpenAIOkHttpClient;353import com.openai.client.okhttp.OpenAIOkHttpClient;

354import com.openai.core.http.HttpClient;354import com.openai.core.http.HttpClient;

355import com.openai.errors.SubjectTokenProviderException;355import com.openai.errors.SubjectTokenProviderException;

356import com.openai.models.ChatModel;

357import com.openai.models.responses.ResponseCreateParams;356import com.openai.models.responses.ResponseCreateParams;

358import java.util.concurrent.CompletableFuture;357import java.util.concurrent.CompletableFuture;

359import software.amazon.awssdk.regions.Region;358import software.amazon.awssdk.regions.Region;


380 @Override379 @Override

381 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {380 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {

382 try {381 try {

383 String token = stsClient.getWebIdentityToken(GetWebIdentityTokenRequest.builder()382 String token =

383 stsClient

384 .getWebIdentityToken(

385 GetWebIdentityTokenRequest.builder()

384 .audience(audience)386 .audience(audience)

385 .durationSeconds(300)387 .durationSeconds(300)

386 .signingAlgorithm("ES384")388 .signingAlgorithm("ES384")

387 .build()).webIdentityToken();389 .build())

390 .webIdentityToken();

388 391 

389 if (token == null || token.isEmpty()) {392 if (token == null || token.isEmpty()) {

390 throw new SubjectTokenProviderException(393 throw new SubjectTokenProviderException(

391 "aws-outbound",394 "aws-outbound", "AWS STS did not return a web identity token", null);

392 "AWS STS did not return a web identity token",

393 null);

394 }395 }

395 396 

396 return token;397 return token;


398 throw e;399 throw e;

399 } catch (Exception e) {400 } catch (Exception e) {

400 throw new SubjectTokenProviderException(401 throw new SubjectTokenProviderException(

401 "aws-outbound",402 "aws-outbound", "failed to request AWS web identity token", e);

402 "failed to request AWS web identity token",

403 e);

404 }403 }

405 }404 }

406 405 

407 @Override406 @Override

408 public CompletableFuture<String> getTokenAsync(407 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

409 HttpClient httpClient, JsonMapper jsonMapper) {

410 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));408 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

411 }409 }

412 }410 }

413 411 

414 public static void main(String[] args) {412 public static void main(String[] args) {

415 String audience = System.getenv("OPENAI_WIF_AUDIENCE");413 String audience = System.getenv("OPENAI_WIF_AUDIENCE");

416 StsClient stsClient = StsClient.builder()414 StsClient stsClient =

417 .region(Region.of(System.getenv("AWS_REGION")))415 StsClient.builder().region(Region.of(System.getenv("AWS_REGION"))).build();

418 .build();

419 416 

420 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()417 WorkloadIdentity workloadIdentity =

418 WorkloadIdentity.builder()

421 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))419 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

422 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))420 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

423 .provider(new AwsOutboundWebIdentityTokenProvider(stsClient, audience))421 .provider(new AwsOutboundWebIdentityTokenProvider(stsClient, audience))

424 .build();422 .build();

425 423 

426 OpenAIClient client = OpenAIOkHttpClient.builder()424 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

427 .workloadIdentity(workloadIdentity)

428 .build();

429 425 

430 ResponseCreateParams params = ResponseCreateParams.builder()426 ResponseCreateParams params =

431 .model(ChatModel.GPT_4_1_MINI)427 ResponseCreateParams.builder()

428 .model("gpt-5.6-terra")

432 .input("Say hello from AWS outbound workload identity federation.")429 .input("Say hello from AWS outbound workload identity federation.")

433 .build();430 .build();

434 431 


803import com.openai.client.okhttp.OpenAIOkHttpClient;800import com.openai.client.okhttp.OpenAIOkHttpClient;

804import com.openai.core.http.HttpClient;801import com.openai.core.http.HttpClient;

805import com.openai.errors.SubjectTokenProviderException;802import com.openai.errors.SubjectTokenProviderException;

806import com.openai.models.ChatModel;

807import com.openai.models.responses.ResponseCreateParams;803import com.openai.models.responses.ResponseCreateParams;

808import java.nio.file.Files;804import java.nio.file.Files;

809import java.nio.file.Path;805import java.nio.file.Path;


833 token = Files.readString(tokenPath).trim();829 token = Files.readString(tokenPath).trim();

834 } catch (Exception e) {830 } catch (Exception e) {

835 throw new SubjectTokenProviderException(831 throw new SubjectTokenProviderException(

836 "aws-eks",832 "aws-eks", "failed to read mounted EKS service account token", e);

837 "failed to read mounted EKS service account token",

838 e);

839 }833 }

840 834 

841 if (token.isEmpty()) {835 if (token.isEmpty()) {

842 throw new SubjectTokenProviderException(836 throw new SubjectTokenProviderException(

843 "aws-eks",837 "aws-eks", "mounted EKS service account token is empty", null);

844 "mounted EKS service account token is empty",

845 null);

846 }838 }

847 839 

848 return token;840 return token;

849 }841 }

850 842 

851 @Override843 @Override

852 public CompletableFuture<String> getTokenAsync(844 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

853 HttpClient httpClient, JsonMapper jsonMapper) {

854 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));845 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

855 }846 }

856 }847 }

857 848 

858 public static void main(String[] args) {849 public static void main(String[] args) {

859 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()850 WorkloadIdentity workloadIdentity =

851 WorkloadIdentity.builder()

860 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))852 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

861 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))853 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

862 .provider(new MountedEksServiceAccountTokenProvider(TOKEN_PATH))854 .provider(new MountedEksServiceAccountTokenProvider(TOKEN_PATH))

863 .build();855 .build();

864 856 

865 OpenAIClient client = OpenAIOkHttpClient.builder()857 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

866 .workloadIdentity(workloadIdentity)

867 .build();

868 858 

869 ResponseCreateParams params = ResponseCreateParams.builder()859 ResponseCreateParams params =

870 .model(ChatModel.GPT_4_1_MINI)860 ResponseCreateParams.builder()

861 .model("gpt-5.6-terra")

871 .input("Say hello from AWS workload identity federation.")862 .input("Say hello from AWS workload identity federation.")

872 .build();863 .build();

873 864 

Details

408import com.fasterxml.jackson.databind.JsonNode;408import com.fasterxml.jackson.databind.JsonNode;

409import com.fasterxml.jackson.databind.json.JsonMapper;409import com.fasterxml.jackson.databind.json.JsonMapper;

410import com.openai.auth.SubjectTokenProvider;410import com.openai.auth.SubjectTokenProvider;

411import com.openai.errors.SubjectTokenProviderException;

412import com.openai.auth.SubjectTokenType;411import com.openai.auth.SubjectTokenType;

413import com.openai.auth.WorkloadIdentity;412import com.openai.auth.WorkloadIdentity;

414import com.openai.client.OpenAIClient;413import com.openai.client.OpenAIClient;

415import com.openai.client.okhttp.OpenAIOkHttpClient;414import com.openai.client.okhttp.OpenAIOkHttpClient;

416import com.openai.models.ChatModel;415import com.openai.errors.SubjectTokenProviderException;

417import com.openai.models.responses.ResponseCreateParams;416import com.openai.models.responses.ResponseCreateParams;

418import java.net.URI;417import java.net.URI;

419import java.net.URLEncoder;418import java.net.URLEncoder;


442 }441 }

443 442 

444 @Override443 @Override

445 public String getToken(444 public String getToken(com.openai.core.http.HttpClient httpClient, JsonMapper jsonMapper) {

446 com.openai.core.http.HttpClient httpClient, JsonMapper jsonMapper) {

447 try {445 try {

448 String separator = requestUrl.contains("?") ? "&" : "?";446 String separator = requestUrl.contains("?") ? "&" : "?";

449 URI uri = URI.create(447 URI uri =

448 URI.create(

450 requestUrl449 requestUrl

451 + separator450 + separator

452 + "audience="451 + "audience="

453 + URLEncoder.encode(audience, StandardCharsets.UTF_8));452 + URLEncoder.encode(audience, StandardCharsets.UTF_8));

454 453 

455 HttpRequest request = HttpRequest.newBuilder(uri)454 HttpRequest request =

455 HttpRequest.newBuilder(uri)

456 .header("Authorization", "bearer " + requestToken)456 .header("Authorization", "bearer " + requestToken)

457 .GET()457 .GET()

458 .build();458 .build();

459 459 

460 HttpResponse<String> response = java.net.http.HttpClient.newHttpClient()460 HttpResponse<String> response =

461 java.net.http.HttpClient.newHttpClient()

461 .send(request, HttpResponse.BodyHandlers.ofString());462 .send(request, HttpResponse.BodyHandlers.ofString());

462 463 

463 if (response.statusCode() < 200 || response.statusCode() >= 300) {464 if (response.statusCode() < 200 || response.statusCode() >= 300) {

464 throw new SubjectTokenProviderException(465 throw new SubjectTokenProviderException(

465 "github-actions",466 "github-actions",

466 "GitHub OIDC token request failed with status "467 "GitHub OIDC token request failed with status " + response.statusCode(),

467 + response.statusCode(),

468 null);468 null);

469 }469 }

470 470 


472 String token = payload.path("value").asText("");472 String token = payload.path("value").asText("");

473 if (token.isEmpty()) {473 if (token.isEmpty()) {

474 throw new SubjectTokenProviderException(474 throw new SubjectTokenProviderException(

475 "github-actions",475 "github-actions", "GitHub OIDC token response did not include a value", null);

476 "GitHub OIDC token response did not include a value",

477 null);

478 }476 }

479 477 

480 return token;478 return token;


482 throw e;480 throw e;

483 } catch (Exception e) {481 } catch (Exception e) {

484 throw new SubjectTokenProviderException(482 throw new SubjectTokenProviderException(

485 "github-actions",483 "github-actions", "failed to request GitHub OIDC token", e);

486 "failed to request GitHub OIDC token",

487 e);

488 }484 }

489 }485 }

490 486 


496 }492 }

497 493 

498 public static void main(String[] args) {494 public static void main(String[] args) {

499 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()495 WorkloadIdentity workloadIdentity =

496 WorkloadIdentity.builder()

500 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))497 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

501 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))498 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

502 .provider(new GitHubActionsOidcTokenProvider(499 .provider(

500 new GitHubActionsOidcTokenProvider(

503 System.getenv("ACTIONS_ID_TOKEN_REQUEST_URL"),501 System.getenv("ACTIONS_ID_TOKEN_REQUEST_URL"),

504 System.getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN"),502 System.getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN"),

505 System.getenv("OPENAI_WIF_AUDIENCE")))503 System.getenv("OPENAI_WIF_AUDIENCE")))

506 .build();504 .build();

507 505 

508 OpenAIClient client = OpenAIOkHttpClient.builder()506 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

509 .workloadIdentity(workloadIdentity)

510 .build();

511 507 

512 ResponseCreateParams params = ResponseCreateParams.builder()508 ResponseCreateParams params =

513 .model(ChatModel.GPT_4_1_MINI)509 ResponseCreateParams.builder()

510 .model("gpt-5.6-terra")

514 .input("Say hello from GitHub Actions workload identity federation.")511 .input("Say hello from GitHub Actions workload identity federation.")

515 .build();512 .build();

516 513 

Details

341import com.openai.client.okhttp.OpenAIOkHttpClient;341import com.openai.client.okhttp.OpenAIOkHttpClient;

342import com.openai.core.http.HttpClient;342import com.openai.core.http.HttpClient;

343import com.openai.errors.SubjectTokenProviderException;343import com.openai.errors.SubjectTokenProviderException;

344import com.openai.models.ChatModel;

345import com.openai.models.responses.ResponseCreateParams;344import com.openai.models.responses.ResponseCreateParams;

346import java.net.URI;345import java.net.URI;

347import java.net.URLEncoder;346import java.net.URLEncoder;


372 @Override371 @Override

373 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {372 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {

374 try {373 try {

375 String query = "audience="374 String query =

376 + URLEncoder.encode(audience, StandardCharsets.UTF_8)375 "audience=" + URLEncoder.encode(audience, StandardCharsets.UTF_8) + "&format=full";

377 + "&format=full";376 HttpRequest request =

378 HttpRequest request = HttpRequest.newBuilder()377 HttpRequest.newBuilder()

379 .uri(URI.create(METADATA_ENDPOINT + "?" + query))378 .uri(URI.create(METADATA_ENDPOINT + "?" + query))

380 .header("Metadata-Flavor", "Google")379 .header("Metadata-Flavor", "Google")

381 .GET()380 .GET()

382 .build();381 .build();

383 382 

384 HttpResponse<String> response = java.net.http.HttpClient.newHttpClient()383 HttpResponse<String> response =

384 java.net.http.HttpClient.newHttpClient()

385 .send(request, HttpResponse.BodyHandlers.ofString());385 .send(request, HttpResponse.BodyHandlers.ofString());

386 if (response.statusCode() < 200 || response.statusCode() >= 300) {386 if (response.statusCode() < 200 || response.statusCode() >= 300) {

387 throw new SubjectTokenProviderException(387 throw new SubjectTokenProviderException(

388 "google-metadata",388 "google-metadata",

389 "Google metadata token request failed with status "389 "Google metadata token request failed with status " + response.statusCode(),

390 + response.statusCode(),

391 null);390 null);

392 }391 }

393 392 

394 String token = response.body().trim();393 String token = response.body().trim();

395 if (token.isEmpty()) {394 if (token.isEmpty()) {

396 throw new SubjectTokenProviderException(395 throw new SubjectTokenProviderException(

397 "google-metadata",396 "google-metadata", "Google metadata server did not return an identity token", null);

398 "Google metadata server did not return an identity token",

399 null);

400 }397 }

401 398 

402 return token;399 return token;


404 throw e;401 throw e;

405 } catch (Exception e) {402 } catch (Exception e) {

406 throw new SubjectTokenProviderException(403 throw new SubjectTokenProviderException(

407 "google-metadata",404 "google-metadata", "failed to request Google identity token", e);

408 "failed to request Google identity token",

409 e);

410 }405 }

411 }406 }

412 407 

413 @Override408 @Override

414 public CompletableFuture<String> getTokenAsync(409 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

415 HttpClient httpClient, JsonMapper jsonMapper) {

416 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));410 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

417 }411 }

418 }412 }

419 413 

420 public static void main(String[] args) {414 public static void main(String[] args) {

421 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()415 WorkloadIdentity workloadIdentity =

416 WorkloadIdentity.builder()

422 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))417 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

423 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))418 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

424 .provider(new GoogleMetadataIdentityTokenProvider(419 .provider(new GoogleMetadataIdentityTokenProvider(System.getenv("OPENAI_WIF_AUDIENCE")))

425 System.getenv("OPENAI_WIF_AUDIENCE")))

426 .build();420 .build();

427 421 

428 OpenAIClient client = OpenAIOkHttpClient.builder()422 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

429 .workloadIdentity(workloadIdentity)

430 .build();

431 423 

432 ResponseCreateParams params = ResponseCreateParams.builder()424 ResponseCreateParams params =

433 .model(ChatModel.GPT_4_1_MINI)425 ResponseCreateParams.builder()

426 .model("gpt-5.6-terra")

434 .input("Say hello from Google Cloud workload identity federation.")427 .input("Say hello from Google Cloud workload identity federation.")

435 .build();428 .build();

436 429 


828import com.openai.client.okhttp.OpenAIOkHttpClient;821import com.openai.client.okhttp.OpenAIOkHttpClient;

829import com.openai.core.http.HttpClient;822import com.openai.core.http.HttpClient;

830import com.openai.errors.SubjectTokenProviderException;823import com.openai.errors.SubjectTokenProviderException;

831import com.openai.models.ChatModel;

832import com.openai.models.responses.ResponseCreateParams;824import com.openai.models.responses.ResponseCreateParams;

833import java.nio.file.Files;825import java.nio.file.Files;

834import java.nio.file.Path;826import java.nio.file.Path;


858 token = Files.readString(tokenPath).trim();850 token = Files.readString(tokenPath).trim();

859 } catch (Exception e) {851 } catch (Exception e) {

860 throw new SubjectTokenProviderException(852 throw new SubjectTokenProviderException(

861 "google-gke",853 "google-gke", "failed to read mounted GKE service account token", e);

862 "failed to read mounted GKE service account token",

863 e);

864 }854 }

865 855 

866 if (token.isEmpty()) {856 if (token.isEmpty()) {

867 throw new SubjectTokenProviderException(857 throw new SubjectTokenProviderException(

868 "google-gke",858 "google-gke", "mounted GKE service account token is empty", null);

869 "mounted GKE service account token is empty",

870 null);

871 }859 }

872 860 

873 return token;861 return token;

874 }862 }

875 863 

876 @Override864 @Override

877 public CompletableFuture<String> getTokenAsync(865 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

878 HttpClient httpClient, JsonMapper jsonMapper) {

879 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));866 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

880 }867 }

881 }868 }

882 869 

883 public static void main(String[] args) {870 public static void main(String[] args) {

884 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()871 WorkloadIdentity workloadIdentity =

872 WorkloadIdentity.builder()

885 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))873 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

886 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))874 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

887 .provider(new MountedGkeServiceAccountTokenProvider(TOKEN_PATH))875 .provider(new MountedGkeServiceAccountTokenProvider(TOKEN_PATH))

888 .build();876 .build();

889 877 

890 OpenAIClient client = OpenAIOkHttpClient.builder()878 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

891 .workloadIdentity(workloadIdentity)

892 .build();

893 879 

894 ResponseCreateParams params = ResponseCreateParams.builder()880 ResponseCreateParams params =

895 .model(ChatModel.GPT_4_1_MINI)881 ResponseCreateParams.builder()

882 .model("gpt-5.6-terra")

896 .input("Say hello from Google GKE workload identity federation.")883 .input("Say hello from Google GKE workload identity federation.")

897 .build();884 .build();

898 885 

Details

293import com.openai.client.okhttp.OpenAIOkHttpClient;293import com.openai.client.okhttp.OpenAIOkHttpClient;

294import com.openai.core.http.HttpClient;294import com.openai.core.http.HttpClient;

295import com.openai.errors.SubjectTokenProviderException;295import com.openai.errors.SubjectTokenProviderException;

296import com.openai.models.ChatModel;

297import com.openai.models.responses.ResponseCreateParams;296import com.openai.models.responses.ResponseCreateParams;

298import java.nio.file.Files;297import java.nio.file.Files;

299import java.nio.file.Path;298import java.nio.file.Path;


323 token = Files.readString(tokenPath).trim();322 token = Files.readString(tokenPath).trim();

324 } catch (Exception e) {323 } catch (Exception e) {

325 throw new SubjectTokenProviderException(324 throw new SubjectTokenProviderException(

326 "kubernetes",325 "kubernetes", "failed to read mounted service account token", e);

327 "failed to read mounted service account token",

328 e);

329 }326 }

330 327 

331 if (token.isEmpty()) {328 if (token.isEmpty()) {

332 throw new SubjectTokenProviderException(329 throw new SubjectTokenProviderException(

333 "kubernetes",330 "kubernetes", "mounted service account token is empty", null);

334 "mounted service account token is empty",

335 null);

336 }331 }

337 332 

338 return token;333 return token;

339 }334 }

340 335 

341 @Override336 @Override

342 public CompletableFuture<String> getTokenAsync(337 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

343 HttpClient httpClient, JsonMapper jsonMapper) {

344 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));338 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

345 }339 }

346 }340 }

347 341 

348 public static void main(String[] args) {342 public static void main(String[] args) {

349 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()343 WorkloadIdentity workloadIdentity =

344 WorkloadIdentity.builder()

350 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))345 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

351 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))346 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

352 .provider(new MountedServiceAccountTokenProvider(TOKEN_PATH))347 .provider(new MountedServiceAccountTokenProvider(TOKEN_PATH))

353 .build();348 .build();

354 349 

355 OpenAIClient client = OpenAIOkHttpClient.builder()350 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

356 .workloadIdentity(workloadIdentity)

357 .build();

358 351 

359 ResponseCreateParams params = ResponseCreateParams.builder()352 ResponseCreateParams params =

360 .model(ChatModel.GPT_4_1_MINI)353 ResponseCreateParams.builder()

354 .model("gpt-5.6-terra")

361 .input("Say hello from Kubernetes workload identity federation.")355 .input("Say hello from Kubernetes workload identity federation.")

362 .build();356 .build();

363 357 

Details

362import com.openai.client.okhttp.OpenAIOkHttpClient;362import com.openai.client.okhttp.OpenAIOkHttpClient;

363import com.openai.core.http.HttpClient;363import com.openai.core.http.HttpClient;

364import com.openai.errors.SubjectTokenProviderException;364import com.openai.errors.SubjectTokenProviderException;

365import com.openai.models.ChatModel;

366import com.openai.models.responses.ResponseCreateParams;365import com.openai.models.responses.ResponseCreateParams;

367import java.net.URI;366import java.net.URI;

368import java.net.URLEncoder;367import java.net.URLEncoder;


392 @Override391 @Override

393 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {392 public String getToken(HttpClient httpClient, JsonMapper jsonMapper) {

394 try {393 try {

395 String query = "api-version=2018-02-01&resource="394 String query =

395 "api-version=2018-02-01&resource="

396 + URLEncoder.encode(resource, StandardCharsets.UTF_8);396 + URLEncoder.encode(resource, StandardCharsets.UTF_8);

397 String clientId = System.getenv("AZURE_CLIENT_ID");397 String clientId = System.getenv("AZURE_CLIENT_ID");

398 if (clientId != null && !clientId.isEmpty()) {398 if (clientId != null && !clientId.isEmpty()) {

399 query += "&client_id="399 query += "&client_id=" + URLEncoder.encode(clientId, StandardCharsets.UTF_8);

400 + URLEncoder.encode(clientId, StandardCharsets.UTF_8);

401 }400 }

402 401 

403 HttpRequest request = HttpRequest.newBuilder()402 HttpRequest request =

403 HttpRequest.newBuilder()

404 .uri(URI.create(IMDS_ENDPOINT + "?" + query))404 .uri(URI.create(IMDS_ENDPOINT + "?" + query))

405 .header("Metadata", "true")405 .header("Metadata", "true")

406 .GET()406 .GET()

407 .build();407 .build();

408 408 

409 HttpResponse<String> response = java.net.http.HttpClient.newHttpClient()409 HttpResponse<String> response =

410 java.net.http.HttpClient.newHttpClient()

410 .send(request, HttpResponse.BodyHandlers.ofString());411 .send(request, HttpResponse.BodyHandlers.ofString());

411 if (response.statusCode() < 200 || response.statusCode() >= 300) {412 if (response.statusCode() < 200 || response.statusCode() >= 300) {

412 throw new SubjectTokenProviderException(413 throw new SubjectTokenProviderException(

413 "azure-managed-identity",414 "azure-managed-identity",

414 "Azure IMDS token request failed with status "415 "Azure IMDS token request failed with status " + response.statusCode(),

415 + response.statusCode(),

416 null);416 null);

417 }417 }

418 418 


420 String token = body.path("access_token").asText();420 String token = body.path("access_token").asText();

421 if (token.isEmpty()) {421 if (token.isEmpty()) {

422 throw new SubjectTokenProviderException(422 throw new SubjectTokenProviderException(

423 "azure-managed-identity",423 "azure-managed-identity", "Azure IMDS did not return an access token", null);

424 "Azure IMDS did not return an access token",

425 null);

426 }424 }

427 425 

428 return token;426 return token;


430 throw e;428 throw e;

431 } catch (Exception e) {429 } catch (Exception e) {

432 throw new SubjectTokenProviderException(430 throw new SubjectTokenProviderException(

433 "azure-managed-identity",431 "azure-managed-identity", "failed to request Azure managed identity token", e);

434 "failed to request Azure managed identity token",

435 e);

436 }432 }

437 }433 }

438 434 

439 @Override435 @Override

440 public CompletableFuture<String> getTokenAsync(436 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

441 HttpClient httpClient, JsonMapper jsonMapper) {

442 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));437 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

443 }438 }

444 }439 }

445 440 

446 public static void main(String[] args) {441 public static void main(String[] args) {

447 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()442 WorkloadIdentity workloadIdentity =

443 WorkloadIdentity.builder()

448 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))444 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

449 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))445 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

450 .provider(new AzureManagedIdentityTokenProvider(446 .provider(new AzureManagedIdentityTokenProvider(System.getenv("OPENAI_WIF_AUDIENCE")))

451 System.getenv("OPENAI_WIF_AUDIENCE")))

452 .build();447 .build();

453 448 

454 OpenAIClient client = OpenAIOkHttpClient.builder()449 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

455 .workloadIdentity(workloadIdentity)

456 .build();

457 450 

458 ResponseCreateParams params = ResponseCreateParams.builder()451 ResponseCreateParams params =

459 .model(ChatModel.GPT_4_1_MINI)452 ResponseCreateParams.builder()

453 .model("gpt-5.6-terra")

460 .input("Say hello from Azure managed identity workload identity federation.")454 .input("Say hello from Azure managed identity workload identity federation.")

461 .build();455 .build();

462 456 


865import com.openai.client.okhttp.OpenAIOkHttpClient;859import com.openai.client.okhttp.OpenAIOkHttpClient;

866import com.openai.core.http.HttpClient;860import com.openai.core.http.HttpClient;

867import com.openai.errors.SubjectTokenProviderException;861import com.openai.errors.SubjectTokenProviderException;

868import com.openai.models.ChatModel;

869import com.openai.models.responses.ResponseCreateParams;862import com.openai.models.responses.ResponseCreateParams;

870import java.nio.file.Files;863import java.nio.file.Files;

871import java.nio.file.Path;864import java.nio.file.Path;


895 token = Files.readString(tokenPath).trim();888 token = Files.readString(tokenPath).trim();

896 } catch (Exception e) {889 } catch (Exception e) {

897 throw new SubjectTokenProviderException(890 throw new SubjectTokenProviderException(

898 "azure-aks",891 "azure-aks", "failed to read mounted AKS service account token", e);

899 "failed to read mounted AKS service account token",

900 e);

901 }892 }

902 893 

903 if (token.isEmpty()) {894 if (token.isEmpty()) {

904 throw new SubjectTokenProviderException(895 throw new SubjectTokenProviderException(

905 "azure-aks",896 "azure-aks", "mounted AKS service account token is empty", null);

906 "mounted AKS service account token is empty",

907 null);

908 }897 }

909 898 

910 return token;899 return token;

911 }900 }

912 901 

913 @Override902 @Override

914 public CompletableFuture<String> getTokenAsync(903 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

915 HttpClient httpClient, JsonMapper jsonMapper) {

916 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));904 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

917 }905 }

918 }906 }

919 907 

920 public static void main(String[] args) {908 public static void main(String[] args) {

921 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()909 WorkloadIdentity workloadIdentity =

910 WorkloadIdentity.builder()

922 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))911 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

923 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))912 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

924 .provider(new MountedAksServiceAccountTokenProvider(TOKEN_PATH))913 .provider(new MountedAksServiceAccountTokenProvider(TOKEN_PATH))

925 .build();914 .build();

926 915 

927 OpenAIClient client = OpenAIOkHttpClient.builder()916 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

928 .workloadIdentity(workloadIdentity)

929 .build();

930 917 

931 ResponseCreateParams params = ResponseCreateParams.builder()918 ResponseCreateParams params =

932 .model(ChatModel.GPT_4_1_MINI)919 ResponseCreateParams.builder()

920 .model("gpt-5.6-terra")

933 .input("Say hello from AKS workload identity federation.")921 .input("Say hello from AKS workload identity federation.")

934 .build();922 .build();

935 923 

Details

322import com.openai.client.okhttp.OpenAIOkHttpClient;322import com.openai.client.okhttp.OpenAIOkHttpClient;

323import com.openai.core.http.HttpClient;323import com.openai.core.http.HttpClient;

324import com.openai.errors.SubjectTokenProviderException;324import com.openai.errors.SubjectTokenProviderException;

325import com.openai.models.ChatModel;

326import com.openai.models.responses.ResponseCreateParams;325import com.openai.models.responses.ResponseCreateParams;

327import java.nio.file.Files;326import java.nio.file.Files;

328import java.nio.file.Path;327import java.nio.file.Path;


351 try {350 try {

352 token = Files.readString(tokenPath).trim();351 token = Files.readString(tokenPath).trim();

353 } catch (Exception e) {352 } catch (Exception e) {

354 throw new SubjectTokenProviderException(353 throw new SubjectTokenProviderException("spiffe", "failed to read SPIFFE JWT-SVID", e);

355 "spiffe",

356 "failed to read SPIFFE JWT-SVID",

357 e);

358 }354 }

359 355 

360 if (token.isEmpty()) {356 if (token.isEmpty()) {

361 throw new SubjectTokenProviderException(357 throw new SubjectTokenProviderException("spiffe", "SPIFFE JWT-SVID file is empty", null);

362 "spiffe",

363 "SPIFFE JWT-SVID file is empty",

364 null);

365 }358 }

366 359 

367 return token;360 return token;

368 }361 }

369 362 

370 @Override363 @Override

371 public CompletableFuture<String> getTokenAsync(364 public CompletableFuture<String> getTokenAsync(HttpClient httpClient, JsonMapper jsonMapper) {

372 HttpClient httpClient, JsonMapper jsonMapper) {

373 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));365 return CompletableFuture.supplyAsync(() -> getToken(httpClient, jsonMapper));

374 }366 }

375 }367 }

376 368 

377 public static void main(String[] args) {369 public static void main(String[] args) {

378 WorkloadIdentity workloadIdentity = WorkloadIdentity.builder()370 WorkloadIdentity workloadIdentity =

371 WorkloadIdentity.builder()

379 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))372 .identityProviderId(System.getenv("OPENAI_IDENTITY_PROVIDER_ID"))

380 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))373 .serviceAccountId(System.getenv("OPENAI_SERVICE_ACCOUNT_ID"))

381 .provider(new SpiffeJwtSvidProvider(TOKEN_PATH))374 .provider(new SpiffeJwtSvidProvider(TOKEN_PATH))

382 .build();375 .build();

383 376 

384 OpenAIClient client = OpenAIOkHttpClient.builder()377 OpenAIClient client = OpenAIOkHttpClient.builder().workloadIdentity(workloadIdentity).build();

385 .workloadIdentity(workloadIdentity)

386 .build();

387 378 

388 ResponseCreateParams params = ResponseCreateParams.builder()379 ResponseCreateParams params =

389 .model(ChatModel.GPT_4_1_MINI)380 ResponseCreateParams.builder()

381 .model("gpt-5.6-terra")

390 .input("Say hello from SPIFFE workload identity federation.")382 .input("Say hello from SPIFFE workload identity federation.")

391 .build();383 .build();

392 384