Keeper Secrets Manager integrates with Oracle Key Vault in order to provide protection for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all your secret credentials.
Features
Encrypt and Decrypt your Keeper Secrets Manager configuration files with Oracle Key Vault
Protect against unauthorized access to your Secrets Manager connections
Requires only minor changes to code for immediate protection. Works with all Keeper Secrets Manager SDK functionality
Prerequisites
OCI KMS Key needs ENCRYPT and DECRYPT permissions.
Setup
1. Install Module
Setting up project using Gradle or Maven
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("com.keepersecurity.secrets-manager:oracle:1.0.0")
implementation("com.keepersecurity.secrets-manager:core:17.0.0")
implementation("com.oracle.oci.sdk:oci-java-sdk-keymanagement:3.60.0")
implementation("com.oracle.oci.sdk:oci-java-sdk-common-httpclient-jersey:3.60.0") // or the latest version
implementation("com.oracle.oci.sdk:oci-java-sdk-common:3.60.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
implementation("com.google.code.gson:gson:2.12.1")
implementation("org.slf4j:slf4j-simple:2.0.16")
implementation("org.bouncycastle:bc-fips:1.0.2.4")
}
The Secrets Manager oracle KSM module Integration can be installed using
go get github.com/keeper-security/secrets-manager-go/integrations/oracle
2. Configure Oracle KV Connection
Ensure that you have an Oracle Key Vault instance available, and you know its OCID (Oracle Cloud Identifier). By default, the `oci key management` library will use the default OCI configuration file (~/.oci/config)
See the Oracle documentation for more information on setting up an Oracle Keys:
Alternatively, You will need to add the correct configuration for your OCI environment, including the details for accessing Oracle Key Vault.
The configuration file should look like this (replace with your actual details):
Once Oracle connection has been configured, You can fetch the Key to encrypt / decrypt KSM configuration using integration and you need to tell the Secrets Manager SDK to utilize the KMS as storage.
Using Oracle Key Vault Integration
Once setup, the Secrets Manager Oracle Key Vault integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the OCI Keys in order to manage the encryption and decryption of the KSM configuration file.
Using Specified Connection credentials
To do this, create OracleKeyValueStorage instance and use this in SecretManagerOptions constructor.
The OracleKeyValueStorage will require the name of the Secrets Manager configuration file with profile and configuration.
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretmanager.oracle.kv.OracleKeyValueStorage;
import com.keepersecurity.secretmanager.oracle.kv.OracleSessionConfig;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.oracle.bmc.Region;
class Test {
public static void main(String args[]){
String configPath = "<~/.oci/config>";
String cryptoEndpoint = "https://<>-crypto.kms.<oracle_cloud_region>.oraclecloud.com";
String vaultId = "<OCI VAULT ID>";
String keyId = "<OCI KEY ID>";
String keyVersionId = "<OCI KEY VERSION>";
String configFileLocation = "<KSM CONFIG FILE LOCATION>";
String profile = "<OCI CONFIG PROFILE EX: DEFAULT>"; // name of your profile
String oneTimeToken = "<Keeper One Time Token>";
String managementEndpoint = "https://<>-management.kms.<oracle_cloud_region>.oraclecloud.com";
Region region = Region.<cloud_region>;
Security.addProvider(new BouncyCastleFipsProvider());
try{
//set Oracle KV configuration,
OracleSessionConfig oracleSessionConfig = new OracleSessionConfig(configPath, cryptoEndpoint, managementEndpoint, vaultId, keyId, keyVersionId, region);
//Get Storage
OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
initializeStorage(oracleKeyValueStorage, oneTimeToken);
SecretsManagerOptions options = new SecretsManagerOptions(oracleKeyValueStorage);
//getSecrets(options)
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.
The storage will require an Oracle config file location, Oracle configuration profile(if there are multiple profile configurations) and the Oracle KMS Crypto endpoint , Oracle KMS Management endpoint as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS.
To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.
The storage will require a OCI Key ID, key version Id, KMS Crypto endpoint, KMS management endpoint, oracle config file location, configuration profile as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS and OCI session configuration shown below.
To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.
The storage will require a OCI Key ID, key version Id, KMS Crypto endpoint, KMS management endpoint, oracle config file location, configuration profile as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS and OCI session configuration shown below.
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OracleKeyManagement;
using SecretsManager;
public class Program
{
private static async Task getOneIndividualSecret()
{
Console.WriteLine("execution started");
bool changeKey = false;
bool decryptConfiguration = false;
var OCIConfigFileLocation = "location";
var profile = "DEFAULT";
var kmsCryptoEndpoint = "crypto_endpoint";
var kmsManagementEndpoint = "management_endpoint";
var ociSessionConfig1 = new OciSessionConfig(OCIConfigFileLocation, profile, kmsCryptoEndpoint, kmsManagementEndpoint);
var path = "oci_ksm_conf_test.json";
string keyId1 = "key1";
string keyId2 = "key2";
string keyVersionId1 = "key1version";
string keyVersionId2 = "key2version";
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Debug);
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<OracleKeyValueStorage>();
var oracle_storage = new OracleKeyValueStorage(keyId2,keyVersionId2,path,ociSessionConfig1,logger );
var dotnet_access_token = "<accesstoken>";
SecretsManagerClient.InitializeStorage(oracle_storage, dotnet_access_token);
if (changeKey)
{
oracle_storage.ChangeKeyAsync(keyId1,keyVersionId1,null).Wait();
}
if (decryptConfiguration)
{
var conf = await oracle_storage.DecryptConfigAsync(true);
Console.WriteLine(conf);
}
var options = new SecretsManagerOptions(oracle_storage);
var records_1 = await SecretsManagerClient.GetSecrets(options);
records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
}
static async Task Main()
{
await getOneIndividualSecret();
}
}
To do this, use NewOracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.
The NewOracleKeyVaultStorage requires the following parameters to encrypt the KSM configuration using Oracle Vault:
ksmConfigFileName : The file name of KSM configuration.
keyConfig : Provide oracle key credentials KeyID and KeyVersionID.
oracleConfig : Provide oracle credentials VaultManagementEndpoint, VaultCryptoEndpoint.
By default, the oci-keymanagement library will use the default OCI configuration file (~/.oci/config).
We can change key that is used for encrypting the KSM configuration, examples below show the code needed to use it
//The method changeKey(keyID, keyVersion) will be used to encrypt the KSM config file with new Key and version.
String newKeyID = "<new Key ID>";
String newKeyVersion = "<New Key Version>";
OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
oracleKeyValueStorage.changeKey(newKeyID, newKeyVersion); // Change the key for encryption/decryption
// To change the Oracle KMS key used for encryption, you can call the `changeKey` method on the `OciKeyValueStorage` instance.
const storage = await new OciKeyValueStorage(keyId, keyVersionId, configPath, ociSessionConfig).init();
await storage.changeKey(keyId2, keyVersionId2);
// To change the Oracle KMS key used for encryption, you can call the `ChangeKeyAsync` method on the `OracleKeyValueStorage` instance.
// using Microsoft.Extensions.Logging;
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Debug);
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<OracleKeyValueStorage>();
var oracle_storage = new OracleKeyValueStorage(keyId2,keyVersionId2,path,ociSessionConfig1,logger );
// If you want to change the key not oracle config, then pass nil in place of oracle config.
updatedKeyConfig := &oraclekv.KeyConfig{
KeyID: "ocid1.key.oc1.<>.<>.<>",
KeyVersionID: "ocid1.keyversion.oc1.<>.<>.<>.<>",
}
isChanged, err := cfg.ChangeKey(updatedKeyConfig, nil)
Decrypt Config
We can decrypt the config if current implementation is to be migrated onto a different cloud or if you want your raw credentials back. The function accepts a boolean which when set to true will save the decrypted configuration to file and if it is false, will just return decrypted configuration.
OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
oracleKeyValueStorage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
//OR
oracleKeyValueStorage.decryptConfig(true); // Set true as a parameter to extract plaintext and save config as a plaintext.
const storage = await new OciKeyValueStorage(keyId, keyVersionId, config_path, ociSessionConfig).init();
await storage.decryptConfig(true); // Saves to file
const decryptedConfig = await storage.decryptConfig(true); // returns the decrypted config
//To decrypt the config file and save it again in plaintext, you can call the `DecryptConfigAsync` method on the `OracleKeyValueStorage` instance.
var conf = await oracle_storage.DecryptConfigAsync(true);
Console.WriteLine(conf);
cfg := oraclekv.NewOracleKeyVaultStorage(ksmConfigFile, keyConfig, oracleConfig)
secrets_manager := core.NewSecretsManager(
&core.ClientOptions{
Token: oneTimeToken,
Config: cfg,
},
)
// Pass true if you want to save decryptconfig in ksm config file, else pass false.
decryptedConfig, err := cfg.DecryptConfig(true)
Support the
Required Oracle packages: , and .
OCI Key needs ENCRYPT and DECRYPT .
Supports the
Requires the package from OCI SDK.
OCI KMS Key needs ENCRYPT and DECRYPT .
Supports the
Requires oci
User credentials to be used will need to have key vault