Skip to content

Adding AWS Parameter Store Configuration Provider #172

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion ojdbc-provider-aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Provider</a></dt>
<dt><a href="#aws-secrets-manager-config-provider">AWS Secrets Manager Configuration
Provider</a></dt>
<dd>Provides connection properties managed by the Secrets Manager service</dd>
<dt><a href="#aws-parameter-store-config-provider">AWS Parameter Store Configuration
Provider</a></dt>
<dd>Provides connection properties managed by the Systems Manager Parameter Store</dd>
<dt><a href="#common-parameters-for-centralized-config-providers">Common Parameters for Centralized Config Providers</a></dt>
<dd>Common parameters supported by the config providers</dd>
<dt><a href="#caching-configuration">Caching configuration</a></dt>
Expand Down Expand Up @@ -98,7 +101,7 @@ The sample code below executes as expected with the previous configuration.

### Password JSON Object

For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) the password is an object itself with the following spec:
For the JSON type of provider (AWS S3, AWS Secrets Manager, AWS Parameter Store, HTTP/HTTPS, File) the password is an object itself with the following spec:

- type
- Mandatory
Expand All @@ -107,13 +110,15 @@ For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) th
- azurevault
- base64
- awssecretsmanager
- awsparameterstore
- value
- Mandatory
- Possible values
- OCID of the secret (if ocivault)
- Azure Key Vault URI (if azurevault)
- Base64 Encoded password (if base64)
- AWS Secret name (if awssecretsmanager)
- AWS Parameter name (if awsparameterstore)
- field_name
- Optional
- Description: Specifies the key within the secret JSON object from which to extract the password value.
Expand All @@ -135,6 +140,16 @@ jdbc:oracle:thin:@config-awssecretsmanager://{secret-name}

The JSON Payload retrieved by AWS Secrets Manager Provider follows the same format in [AWS S3 Configuration Provider](#json-payload-format).

## AWS Parameter Store Config Provider
Apart from AWS S3 and Secrets Manager, users can also store JSON payload in AWS Systems Manager Parameter Store.
To use it, specify the name of the parameter:

<pre>
jdbc:oracle:thin:@config-awsparameterstore://{parameter-name}
</pre>

The JSON payload stored in the parameter should follow the same format as described in [AWS S3 Configuration Provider](#json-payload-format).

## Common Parameters for Centralized Config Providers
AWS S3 Configuration Provider and AWS Secrets Manager Configuration Provider
share the same sets of parameters for authentication configuration.
Expand Down
3 changes: 3 additions & 0 deletions ojdbc-provider-aws/example-test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,6 @@ AWS_S3_URL=jdbc:oracle:thin:@config-awss3://...

# The URL to test with the AWS Secrets Manager Configuration Provider
AWS_SECRETS_MANAGER_URL=jdbc:oracle:thin:@config-awssecretsmanager://...

# The URL to test with the AWS Parameter Store Configuration Provider
AWS_PARAMETER_STORE_URL=jdbc:oracle:thin:@config-awsparameterstore://...
4 changes: 4 additions & 0 deletions ojdbc-provider-aws/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ssm</artifactId>
</dependency>
<!-- TEST DEPENDENCIES -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
** Copyright (c) 2025 Oracle and/or its affiliates.
**
** The Universal Permissive License (UPL), Version 1.0
**
** Subject to the condition set forth below, permission is hereby granted to any
** person obtaining a copy of this software, associated documentation and/or data
** (collectively the "Software"), free of charge and under any and all copyright
** rights in the Software, and any and all patent rights owned or freely
** licensable by each licensor hereunder covering either (i) the unmodified
** Software as contributed to or provided by such licensor, or (ii) the Larger
** Works (as defined below), to deal in both
**
** (a) the Software, and
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
** one is included with the Software (each a "Larger Work" to which the Software
** is contributed by such licensors),
**
** without restriction, including without limitation the rights to copy, create
** derivative works of, display, perform, and distribute the Software and make,
** use, sell, offer for sale, import, export, have made, and have sold the
** Software and the Larger Work(s), and to sublicense the foregoing rights on
** either these or other terms.
**
** This license is subject to the following condition:
** The above copyright notice and either this complete permission notice or at
** a minimum a reference to the UPL must be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/

package oracle.jdbc.provider.aws.configuration;

import oracle.jdbc.provider.aws.parameterstore.ParameterStoreFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.spi.OracleConfigurationSecretProvider;

import java.util.Base64;
import java.util.Map;

import static oracle.jdbc.provider.aws.configuration.AwsParameterStoreConfigurationProvider.PARAMETER_SET_PARSER;

public class AwsJsonParameterStoreProvider
implements OracleConfigurationSecretProvider {

/**
* {@inheritDoc}
* <p>
* Returns the value of the parameter retrieved from AWS Systems Manager
* Parameter Store.
* </p>
* <p>
* The {@code jsonObject} is expected to be in the following form:
* </p>
*
* <pre>{@code
* "password": {
* "type": "awsparameterstore",
* "value": "/my-app/database-password"
* }
* }</pre>
*
* <p>
* The provider retrieves the parameter specified by the {@code value} field
* from AWS Parameter Store, then encodes it as a Base64 string.
* The encoded value is returned as a {@code char[]} for use with Oracle JDBC's
* centralized configuration.
* </p>
*
* @param map Map object containing key-value pairs parsed from the JSON configuration.
* @return Base64-encoded {@code char[]} representing the retrieved secret value.
*/
@Override
public char[] getSecret(Map<String, String> map) {
ParameterSet parameterSet = PARAMETER_SET_PARSER.parseNamedValues(map);

String parameterValue = ParameterStoreFactory.getInstance()
.request(parameterSet)
.getContent();

return Base64.getEncoder()
.encodeToString(parameterValue.getBytes())
.toCharArray();
}

@Override
public String getSecretType() {
return "awsparameterstore";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
** Copyright (c) 2025 Oracle and/or its affiliates.
**
** The Universal Permissive License (UPL), Version 1.0
**
** Subject to the condition set forth below, permission is hereby granted to any
** person obtaining a copy of this software, associated documentation and/or data
** (collectively the "Software"), free of charge and under any and all copyright
** rights in the Software, and any and all patent rights owned or freely
** licensable by each licensor hereunder covering either (i) the unmodified
** Software as contributed to or provided by such licensor, or (ii) the Larger
** Works (as defined below), to deal in both
**
** (a) the Software, and
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
** one is included with the Software (each a "Larger Work" to which the Software
** is contributed by such licensors),
**
** without restriction, including without limitation the rights to copy, create
** derivative works of, display, perform, and distribute the Software and make,
** use, sell, offer for sale, import, export, have made, and have sold the
** Software and the Larger Work(s), and to sublicense the foregoing rights on
** either these or other terms.
**
** This license is subject to the following condition:
** The above copyright notice and either this complete permission notice or at
** a minimum a reference to the UPL must be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/

package oracle.jdbc.provider.aws.configuration;

import oracle.jdbc.driver.configuration.OracleConfigurationParsableProvider;
import oracle.jdbc.provider.aws.parameterstore.ParameterStoreFactory;
import oracle.jdbc.provider.parameter.Parameter;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.parameter.ParameterSetParser;
import oracle.jdbc.util.OracleConfigurationCache;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import static oracle.jdbc.provider.aws.configuration.AwsConfigurationParameters.KEY;
import static oracle.jdbc.provider.aws.configuration.AwsConfigurationParameters.REGION;

/**
* A provider for JSON payload which contains configuration from AWS Systems
* Manager Parameter Store.
* See {@link #getInputStream(String)} for the spec of the JSON payload.
**/
public class AwsParameterStoreConfigurationProvider
extends OracleConfigurationParsableProvider {

static final ParameterSetParser PARAMETER_SET_PARSER =
AwsConfigurationParameters.configureBuilder(
ParameterSetParser.builder()
.addParameter("value", ParameterStoreFactory.PARAMETER_NAME)
.addParameter("key", KEY)
.addParameter("type", Parameter.create())
.addParameter("AWS_REGION", REGION)
).build();

/**
* {@inheritDoc}
* <p>
* Returns the JSON payload stored in AWS Systems Manager Parameter Store.
* </p>
*
* @param parameterName name of the secret
* @return JSON payload
*/
@Override
public InputStream getInputStream(String parameterName) {
// The JSON “value” field holds the Parameter Store name
final String VALUE = "value";
Map<String, String> opts = new HashMap<>(options);
opts.put(VALUE, parameterName);

ParameterSet params = PARAMETER_SET_PARSER.parseNamedValues(opts);
String json = ParameterStoreFactory.getInstance()
.request(params)
.getContent();

return new ByteArrayInputStream(json.getBytes());
}

@Override
public String getType() {
return "awsparameterstore";
}

/**
* {@inheritDoc}
* @return cache of this provider which is used to store configuration
*/
@Override
public OracleConfigurationCache getCache() {
return CACHE;
}

/**
* {@inheritDoc}
* @return the parser type
*/
@Override
public String getParserType(String location) {
return "json";
}
}
Loading