001/* 002 * Copyright (c) 2026, Oracle and/or its affiliates. 003 * 004 * Licensed under the Universal Permissive License Version 1.0 as shown at 005 * https://oss.oracle.com/licenses/upl/ 006 */ 007package com.oracle.database.selectai.model; 008 009/** 010 * Configuration used to create an Oracle {@code DBMS_CLOUD} credential. 011 * <p> 012 * Select AI profiles reference credentials so the database can authenticate to 013 * an AI provider or object storage service. This configuration supports both 014 * username/password credentials and OCI API signing key credentials. Secret 015 * values are passed to the database credential creation call; they are not used 016 * directly by Java after the credential has been created. 017 * <p> 018 * Secret values are retained in memory as {@link String} values so they can be 019 * bound to {@code DBMS_CLOUD.CREATE_CREDENTIAL}. The SDK does not log password 020 * or private-key values. Applications should not log, persist, or expose this 021 * configuration in diagnostics. 022 * <p> 023 * A name-only configuration can be used to reference or drop an existing 024 * credential. Credential creation validates that the configuration contains 025 * either username/password fields or complete OCI signing-key fields, but not 026 * both. 027 * 028 * @see <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/select-ai-manage-profiles.html"> 029 * Select AI prerequisites and credentials</a> 030 */ 031public final class CredentialConfig { 032 033 /** Database credential name passed to {@code DBMS_CLOUD.CREATE_CREDENTIAL}. */ 034 private final String credentialName; 035 /** Username used for username/password cloud service credentials. */ 036 private final String username; 037 /** Password used for username/password cloud service credentials. */ 038 private final String password; 039 /** OCI user OCID used as the credential username. */ 040 private final String userOcid; 041 /** OCI tenancy OCID associated with the signing key. */ 042 private final String tenancyOcid; 043 /** Private key material used by Oracle Database to sign OCI requests. */ 044 private final String privateKey; 045 /** Fingerprint for the public key uploaded to OCI. */ 046 private final String fingerprint; 047 048 private CredentialConfig(Builder builder) { 049 this.credentialName = builder.credentialName; 050 this.username = builder.username; 051 this.password = builder.password; 052 this.userOcid = builder.userOcid; 053 this.tenancyOcid = builder.tenancyOcid; 054 this.privateKey = builder.privateKey; 055 this.fingerprint = builder.fingerprint; 056 } 057 058 /** 059 * Creates a builder for a credential with the required database credential name. 060 * 061 * @param credentialName database credential name 062 * @return builder initialized with mandatory credential name 063 * @throws IllegalArgumentException when {@code credentialName} is null or blank 064 */ 065 public static Builder builder(String credentialName) { 066 return new Builder(credentialName); 067 } 068 069 /** 070 * Creates a username/password credential configuration. 071 * 072 * @param credentialName database credential name 073 * @param username cloud service username 074 * @param password cloud service password, or {@code null} when the target 075 * service does not require one 076 * @return credential configuration for username/password credential creation 077 * @throws IllegalArgumentException when {@code credentialName} is null or blank 078 */ 079 public static CredentialConfig usernamePassword(String credentialName, 080 String username, 081 String password) { 082 return builder(credentialName) 083 .username(username) 084 .password(password) 085 .build(); 086 } 087 088 /** 089 * Creates an OCI signing-key credential configuration. 090 * 091 * @param credentialName database credential name 092 * @param userOcid OCI user OCID 093 * @param tenancyOcid OCI tenancy OCID 094 * @param privateKey PEM private key material 095 * @param fingerprint OCI API key fingerprint 096 * @return credential configuration for OCI signing-key credential creation 097 * @throws IllegalArgumentException when {@code credentialName} is null or blank 098 */ 099 public static CredentialConfig ociSigningKey(String credentialName, 100 String userOcid, 101 String tenancyOcid, 102 String privateKey, 103 String fingerprint) { 104 return builder(credentialName) 105 .userOcid(userOcid) 106 .tenancyOcid(tenancyOcid) 107 .privateKey(privateKey) 108 .fingerprint(fingerprint) 109 .build(); 110 } 111 112 /** 113 * Returns the database credential name. 114 * 115 * @return credential name 116 */ 117 public String getCredentialName() { 118 return credentialName; 119 } 120 121 /** 122 * Returns the username used for username/password cloud service credentials. 123 * 124 * @return username, or {@code null} when not set 125 */ 126 public String getUsername() { 127 return username; 128 } 129 130 /** 131 * Returns the password. 132 * <p> 133 * This value is sensitive. Do not log, persist, or expose it in diagnostics. 134 * The SDK uses it only to bind DBMS_CLOUD.CREATE_CREDENTIAL parameters. 135 * 136 * @return password, or {@code null} when not set. 137 */ 138 public String getPassword() { 139 return password; 140 } 141 142 /** 143 * Returns the OCI user OCID stored in the credential. 144 * 145 * @return OCI user OCID, or {@code null} when not set 146 */ 147 public String getUserOcid() { 148 return userOcid; 149 } 150 151 /** 152 * Returns the OCI tenancy OCID stored in the credential. 153 * 154 * @return OCI tenancy OCID, or {@code null} when not set 155 */ 156 public String getTenancyOcid() { 157 return tenancyOcid; 158 } 159 160 /** 161 * Returns the private key material stored in the credential request. 162 * <p> 163 * This value is sensitive. Do not log, persist, or expose it in diagnostics. 164 * The SDK uses it only to bind DBMS_CLOUD.CREATE_CREDENTIAL parameters. 165 * 166 * @return private key material, or {@code null} when not set 167 */ 168 public String getPrivateKey() { 169 return privateKey; 170 } 171 172 /** 173 * Returns the fingerprint for the OCI API signing key. 174 * 175 * @return key fingerprint, or {@code null} when not set 176 */ 177 public String getFingerprint() { 178 return fingerprint; 179 } 180 181 /** 182 * Builder for {@link CredentialConfig}. 183 */ 184 public static final class Builder { 185 186 /** Required database credential name. */ 187 private final String credentialName; 188 /** Optional username for username/password credentials. */ 189 private String username; 190 /** Optional password for username/password credentials. */ 191 private String password; 192 /** Optional OCI user OCID. */ 193 private String userOcid; 194 /** Optional OCI tenancy OCID. */ 195 private String tenancyOcid; 196 /** Optional private key material. */ 197 private String privateKey; 198 /** Optional key fingerprint. */ 199 private String fingerprint; 200 201 private Builder(String credentialName) { 202 if (credentialName == null || credentialName.isBlank()) { 203 throw new IllegalArgumentException("credentialName must not be null or blank"); 204 } 205 this.credentialName = credentialName; 206 } 207 208 /** 209 * Sets the username for username/password cloud service credentials. 210 * <p> 211 * A blank username is invalid when this configuration is used to create 212 * a username/password credential. 213 * 214 * @param username cloud service username 215 * @return this builder instance 216 */ 217 public Builder username(String username) { 218 this.username = username; 219 return this; 220 } 221 222 /** 223 * Sets the password for username/password cloud service credentials. 224 * <p> 225 * The password is optional for {@code DBMS_CLOUD.CREATE_CREDENTIAL}; 226 * when not supplied, the SDK passes {@code null} to the database. 227 * Supplying a password without a username is invalid when this 228 * configuration is used to create a credential. 229 * 230 * @param password cloud service password 231 * @return this builder instance 232 */ 233 public Builder password(String password) { 234 this.password = password; 235 return this; 236 } 237 238 /** 239 * Sets the OCI user OCID. 240 * <p> 241 * When this configuration is used to create an OCI signing-key 242 * credential, user OCID, tenancy OCID, private key, and fingerprint must 243 * all be supplied. 244 * 245 * @param userOcid OCI user OCID 246 * @return this builder instance 247 */ 248 public Builder userOcid(String userOcid) { 249 this.userOcid = userOcid; 250 return this; 251 } 252 253 /** 254 * Sets the OCI tenancy OCID. 255 * <p> 256 * When this configuration is used to create an OCI signing-key 257 * credential, user OCID, tenancy OCID, private key, and fingerprint must 258 * all be supplied. 259 * 260 * @param tenancyOcid OCI tenancy OCID 261 * @return this builder instance 262 */ 263 public Builder tenancyOcid(String tenancyOcid) { 264 this.tenancyOcid = tenancyOcid; 265 return this; 266 } 267 268 /** 269 * Sets the PEM private key material. 270 * <p> 271 * This value is sensitive. Do not log, persist, or expose it in 272 * diagnostics. When this configuration is used to create an OCI 273 * signing-key credential, user OCID, tenancy OCID, private key, and 274 * fingerprint must all be supplied. 275 * 276 * @param privateKey private key material 277 * @return this builder instance 278 */ 279 public Builder privateKey(String privateKey) { 280 this.privateKey = privateKey; 281 return this; 282 } 283 284 /** 285 * Sets the OCI public key fingerprint. 286 * <p> 287 * When this configuration is used to create an OCI signing-key 288 * credential, user OCID, tenancy OCID, private key, and fingerprint must 289 * all be supplied. 290 * 291 * @param fingerprint OCI API key fingerprint 292 * @return this builder instance 293 */ 294 public Builder fingerprint(String fingerprint) { 295 this.fingerprint = fingerprint; 296 return this; 297 } 298 299 /** 300 * Builds the immutable credential configuration. 301 * <p> 302 * This method validates only the credential name supplied to 303 * {@link #builder(String)}. Complete create-time validation is performed 304 * by {@code Credential.create()} so name-only configurations remain 305 * usable for credential references and drop operations. 306 * 307 * @return immutable CredentialConfig assembled from current builder state 308 */ 309 public CredentialConfig build() { 310 return new CredentialConfig(this); 311 } 312 } 313 314}