Skip to content

Commit be66175

Browse files
Add Credentials File Authentication for HCP Vault Secret & Improve Field Extraction Logic in HCP Vault Dedicated
1 parent 1583908 commit be66175

File tree

8 files changed

+455
-26
lines changed

8 files changed

+455
-26
lines changed

ojdbc-provider-hashicorp/README.md

+82-9
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ and HashiCorp Vault (HCP).
55

66
## Centralized Config Providers
77
<dl>
8-
<dt><a href="#hcp-vault-secrets-config-provider">HashiCorp Vault Secrets Config Provider</a></dt>
8+
<dt><a href="#hcp-vault-secrets-config-provider">HashiCorp Vault Dedicated Config Provider</a></dt>
99
<dd>Provides connection properties managed by the Vault Secrets service</dd>
10-
<dt><a href="#hcp-vault-dedicated-config-provider">HashiCorp Vault Dedicated Config Provider</a></dt>
10+
<dt><a href="#hcp-vault-dedicated-config-provider">HashiCorp Vault Secret Config Provider</a></dt>
1111
<dd>Provides connection properties managed by the Dedicated Vault service</dd>
1212
<dt><a href="#caching-configuration">Caching configuration</a></dt>
1313
<dd>Caching mechanism adopted by Centralized Config Providers</dd>
@@ -215,19 +215,27 @@ For more information, visit the official documentation: <a href="https://develop
215215

216216
### HCP Vault Secrets
217217

218-
Authentication for the **HCP Vault Secrets** uses the OAuth 2.0 Client Credentials flow.
218+
Authentication for **HCP Vault Secrets** supports two methods:
219219

220-
The `CLIENT_ID` and `CLIENT_SECRET` are used to obtain a Bearer token for authentication,
221-
the Bearer token is then used for making API calls to retrieve secrets from HCP Vault Secrets.
222-
Once authenticated, the secrets can be retrieved using the HashiCorp Vault API.
220+
1. **OAuth 2.0 Client Credentials Flow**
221+
- Uses `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET` to obtain a Bearer token for authentication.
222+
- The token is then used to retrieve secrets from HCP Vault Secrets API.
223223

224-
The generated token is cached and reused until it expires, minimizing API calls to the HCP Vault Secrets.
224+
2. **Credentials File Authentication**
225+
- Uses a JSON file (`creds-cache.json`) containing authentication credentials (`access_token`, `refresh_token`, and `access_token_expiry`). - If the access token is expired, it is automatically refreshed using the stored refresh token.
226+
- If the access token is expired, it is **automatically refreshed** using the stored refresh token.
227+
- This method allows authentication **without requiring direct API credentials**.
228+
229+
The generated token is cached and reused until it expires, minimizing API calls to HCP Vault Secrets.
225230

226231
Secrets can be retrieved from the following API endpoint:
227232
`https://api.cloud.hashicorp.com/secrets/2023-11-28/organizations/$HCP_ORG_ID/projects/$HCP_PROJECT_ID/apps/$APP_NAME/secrets`
228233

229234
For more information, visit the official HashiCorp Vault documentation: [HCP Vault Secrets](https://developer.hashicorp.com/hcp/tutorials/get-started-hcp-vault-secrets/hcp-vault-secrets-retrieve-secret).
230235

236+
#### OAuth 2.0 Client Credentials Flow
237+
238+
This method uses OAuth 2.0 **client credentials** to obtain a **Bearer token**, which is required for authentication.
231239
The provider searches for the following parameters:
232240

233241
<table>
@@ -249,6 +257,66 @@ The provider searches for the following parameters:
249257
<td>The client secret for OAuth 2.0 authentication</td>
250258
<td>Yes</td>
251259
</tr>
260+
</tbody>
261+
</table>
262+
263+
#### CLI CREDENTIALS FILE
264+
This method **retrieves authentication details** from a **JSON file (`creds-cache.json`)** that contains access tokens.
265+
266+
- If **HCP CLI is installed**, a **creds-cache.json** file is **automatically created** in: <code>~/.config/hcp/creds-cache.json</code>
267+
- This file contains **access_token, refresh_token, and access_token_expiry**.
268+
- If **the token is expired**, it is **automatically refreshed** using the **refresh_token**.
269+
- The credentials file should be a JSON file containing the following structure:
270+
271+
```json
272+
{
273+
"login": {
274+
"access_token": "YOUR_ACCESS_TOKEN",
275+
"refresh_token": "YOUR_REFRESH_TOKEN",
276+
"access_token_expiry": "2025-01-01T12:34:56.789Z"
277+
}
278+
}
279+
```
280+
- access_token: The current access token for API authentication.
281+
- refresh_token: The refresh token used to obtain a new access token when expired.
282+
- access_token_expiry: The expiration timestamp of the access_token.
283+
284+
When using this method, the provider will:
285+
* Read the file and validate the access_token.
286+
* Refresh the token if it's expired, using the refresh_token.
287+
* Update the file with the new token details.
288+
289+
The provider searches for the following parameters:
290+
291+
<table>
292+
<thead>
293+
<tr>
294+
<th>Parameter Name</th>
295+
<th>Description</th>
296+
<th>Required</th>
297+
</tr>
298+
</thead>
299+
<tbody>
300+
<tr>
301+
<td><code>HCP_CREDENTIALS_FILE</code></td>
302+
<td>The path of the credentials file ( by default
303+
<code>~/.config/hcp/creds-cache.json</code></td>
304+
<td>No</td>
305+
</tr>
306+
</tbody>
307+
</table>
308+
309+
#### Common Parameters for HCP Vault Secrets authentication methods
310+
311+
<table>
312+
<thead>
313+
<tr>
314+
<th>Parameter Name</th>
315+
<th>Description</th>
316+
<th>Required</th>
317+
</tr>
318+
</thead>
319+
<tbody>
252320
<tr>
253321
<td><code>HCP_ORG_ID</code></td>
254322
<td>The organization ID associated with the Vault</td>
@@ -267,6 +335,7 @@ The provider searches for the following parameters:
267335
</tbody>
268336
</table>
269337

338+
270339
## Config Providers
271340

272341
### HCP Vault Dedicated Config Provider
@@ -394,10 +463,14 @@ For the JSON type of provider (HCP Vault Dedicated, HCP Vault Secrets, HTTP/HTTP
394463
- Secret name (if hcpvaultsecret)
395464
- Text
396465
- field_name (HCP Vault Dedicated only)
397-
- Mandatory
466+
- Optional
398467
- Description: Specifies the key within the secret JSON object to retrieve the password value.
399468
For example, if the secret contains `{ "db-password": "mypassword" }`,
400-
setting `field_name: "db-password"` will extract `"mypassword"`.
469+
setting `field_name: "db-password"` will extract `"mypassword"`.
470+
- **Logic behind the `field_name` attribute:**
471+
- If `field_name` is **specified**, its corresponding value is extracted.
472+
- If the **secret contains only one key-value pair**, that value is **automatically used**.
473+
- If `field_name` is **missing** and **multiple keys exist**, an **error is thrown**.
401474
- authentication
402475
- Optional
403476
- Possible Values

ojdbc-provider-hashicorp/example-test.properties

+4
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,7 @@ HCP_PROJECT_ID=your-project-id
145145

146146
# Name of the secret to be fetched from the application
147147
SECRET_NAME=your-secret-name
148+
149+
# Path to the credentials file containing authentication details
150+
# (By default: ~/.config/hcp/creds-cache.json if using HCP CLI)
151+
HCP_CREDENTIALS_FILE=/path/to/your/creds-cache.json

ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultJsonSecretProvider.java

+20-3
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,18 @@
7070
* }
7171
* }</pre>
7272
*
73+
* <h3>Behavior for Extracting the Secret</h3>
74+
* <ul>
75+
* <li> If {@code field_name} is provided, the corresponding value is
76+
* extracted.</li>
77+
* <li>If the secret contains <b>only one key-value pair</b>, that value
78+
* is automatically selected.</li>
79+
* <li>If multiple keys exist and {@code field_name} is <b>not provided</b>,
80+
* an error is thrown.</li>
81+
* </ul>
7382
* <p>
7483
* The secret path specified in the JSON is used to query the Vault and fetch
75-
* the desired secret. If {@code FIELD_NAME} is provided, the corresponding
76-
* field is extracted from the Vault's JSON response.
84+
* the desired secret.
7785
* </p>
7886
*/
7987
public class DedicatedVaultJsonSecretProvider implements OracleConfigurationJsonSecretProvider {
@@ -99,7 +107,16 @@ public char[] getSecret(OracleJsonObject jsonObject) {
99107
.asJsonObject();
100108

101109
String fieldName = parameterSet.getOptional(FIELD_NAME);
102-
String extractedPassword = String.valueOf(secretJsonObj.get(fieldName));
110+
String extractedPassword;
111+
if (fieldName != null && secretJsonObj.containsKey(fieldName)) {
112+
extractedPassword = secretJsonObj.getString(fieldName);
113+
} else if (secretJsonObj.size() == 1) {
114+
extractedPassword = secretJsonObj.values().iterator().next().toString();
115+
} else {
116+
throw new IllegalStateException(
117+
"FIELD_NAME is required when multiple keys exist in the secret."
118+
);
119+
}
103120

104121
return Base64.getEncoder()
105122
.encodeToString(extractedPassword.getBytes())

ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/authentication/HcpVaultAuthenticationMethod.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,32 @@ public enum HcpVaultAuthenticationMethod {
6464
* by calling the HCP OAuth2 endpoint.
6565
* </p>
6666
*/
67-
CLIENT_CREDENTIALS
67+
CLIENT_CREDENTIALS,
68+
69+
/**
70+
* Authentication using the credentials file generated by the HCP CLI.
71+
* <p>
72+
* This method retrieves an access token from the standard CLI-generated
73+
* credentials file located at
74+
* <code>System.getProperty("user.home") + "/.config/hcp/creds-cache.json"</code>.
75+
* If the token is expired,
76+
* it will be automatically refreshed using the stored refresh token.
77+
* </p>
78+
* <p>
79+
* The credentials file must follow the standard JSON structure containing:
80+
* </p>
81+
* <pre>
82+
* {
83+
* "login": {
84+
* "access_token": "...",
85+
* "refresh_token": "...",
86+
* "access_token_expiry": "..."
87+
* }
88+
* }
89+
* </pre>
90+
* <p>
91+
* The user can provide a custom path to the credentials file if needed.
92+
* </p>
93+
*/
94+
CLI_CREDENTIALS_FILE
6895
}

0 commit comments

Comments
 (0)