Password vault configuration
Introduction
The Continuous Compliance Engine supports the use of HashiCorp, CyberArk, Azure Key Vault, and Google Cloud Platform (GCP) password vaults for connections to the following databases:
Db2, MariaDB, MSSQL, MySQL, Oracle, PostgreSQL, YugabyteDB, CockroachDB, and Sybase.
Utilizing this feature requires the presence of either a HashiCorp, CyberArk, Azure, or GCP vault/secret manager, as well as additional configuration actions on the Continuous Compliance Engine.
Password vault authentication is not supported for containerized masking deployments at this time.
Configuring a password vault on the appliance
Before attempting to access a password vault, the CA certificate for the vault must first be added to the Compliance Engine's trust store. Certificates can be managed through the Delphix Server Setup UI and the steps for doing so can be found on the TrustStore settings page.
Currently, password vaults and the associated credential paths can only be configured on the appliance using the API. The Continuous Compliance Engine's web API includes two endpoints, password-vaults
and credential-paths
, for managing the setup of vaults and credentials.
Setting up a password vault
The POST action on the password-vaults
endpoint is used to provide information on the type of vault to be accessed and the location of the server hosting the vault.
You must put certificates and private keys in a single line (one-liner). To convert an existing certificate or private key to one line (from Linux), you can run:
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' file_name
HashiCorp
For HashiCorp, the request body will be similar to:
{
"name": "HashiVault",
"vaultType": "HASHICORP",
"configJson": {
"host": "123.45.67.89",
"port": 8200,
"namespace": "sample/child",
"authType": "TOKEN",
"token": "hvs.kvITvwsi4gs"
},
"description": "Vault description is optional"
}
Namespaces are only relevant when using the Enterprise version of the HashiCorp product. If this field is specified, it should match the namespace being used on the HashiCorp server.
To use either AppRole or Certificate-based authentication, the following substitutions can be made using the example above.
For AppRole authentication:
"authType": "APPROLE",
"roleId": "your-role-id",
"secretId": "your-secret"
For Certificate-based authentication:
"authType": "CERTIFICATE",
"certificate": "-----BEGIN CERTIFICATE-----\nMIa1ZqA=\n-----END CERTIFICATE-----",
"privateKey": "-----BEGIN RSA PRIVATE KEY-----\nUw9aPq\n-----END RSA PRIVATE KEY-----",
"roleName": "sampleRole"
CyberArk
For CyberArk, the request body will be similar to:
{
"name": "CyberVault",
"vaultType": "CYBERARK",.
"configJson": {
"host": "cyberark01.myserver.com",
"port": 443,
"appId": "MyApp",
"authType": "CERTIFICATE",
"certificate": "-----BEGIN CERTIFICATE-----\nMIa1ZqA=\n-----END CERTIFICATE-----"
"privateKey": "-----BEGIN PRIVATE KEY-----\nMIa1ZqA=\n-----END PRIVATE KEY-----"
},
"description": "Vault description is optional"
}
Azure Key Vault
For Azure, the request body will be similar to:
{
"name": "My Azure Vault",
"vaultType": "AZURE",
"configJson": {
"host": "my-azure-vault-name.vault.azure.net",
"authType": "SECRETS",
"clientId": "your-client-id",
"tenantId": "your-tenant-id",
"clientSecret": "your-client-secret"
},
"description": "Vault description is optional."
}
The client secret will not be seen in API responses due to its sensitive nature.
To use the Certificate-based authentication, make the following substitution to the configJson
:
"configJson": {
"host": "my-azure-vault-name.vault.azure.net",
"authType": "CERTIFICATE",
"clientId": "your-client-id",
"tenantId": "your-tenant-id",
"certificate": "-----BEGIN CERTIFICATE-----\nMIa1ZqA\n-----END CERTIFICATE-----\n"
},
To obtain the clientId
and tenantId
and create a secret or certificate-based authentication method, an App Registration should be created in the Azure account and associated with the Azure Key Vault. Microsoft documentation on the topic can be found here.
Google Cloud Platform
For GCP, where password vault is referred to as a Secret Manager, the request body will be similar to:
{
"name": "GCPVault",
"vaultType": "GCP",
"configJson": {
"authType": "SERVICE_ACCOUNT",
"serviceAccountIdJson": {...}
},
"description": "Vault description is optional"
}
The only authType
for GCP is SERVICE_ACCOUNT
.
The serviceAccountIdJson
value in its entirety is retrieved from the Service Account section of IAM & Admin in the Google account. This is done by creating and downloading a JSON key for the service account. Permissions to create this key must be enabled. The key contains multiple fields and handles all properties of the connection to the secret manager. Google documents the process here. An example of the JSON looks like this:
{
"type": "service_account",
"project_id": "test-project",
"private_key_id": "test-key-id",
"private_key": "test-key",
"client_email": "test-email",
"client_id": "test-client-id",
"auth_uri": "test-auth-uri",
"token_uri": "test-token-uri",
"auth_provider_x509_cert_url": "test-cert-url",
"client_x509_cert_url": "test-client-cert-url"
}
The Google documentation recommends setting up Workload Identity Federation instead of service account ID for some applications. This approach is not supported for masking engine password vaults.
Setting up a credential path
Credential paths are used to specify the location of the credentials within a password vault.
HashiCorp
The Continuous Compliance Engine currently supports two types of HashiCorp secrets engines: database
and key-value-v2
.
The request body for a HashiCorp credential path will be similar to:
{
"credentialPathName": "HashiCredentialPath",
"description": "Credential path description is optional",
"passwordVaultId": 1,
"credentialParameters": {
"engineType": "KEY_VALUE_V2",
"engine": "secret-engine-name",
"path": "secret-path",
"usernameKey": "username",
"passwordKey": "password"
}
}
Database secrets engines support dynamic secrets by generating database credentials based on configured roles. When using a database secrets engine, set engineType
to DATABASE and use role
to specify the name of the role to create credentials against.
"credentialParameters": {
"engineType": "DATABASE",
"engine": "database-engine-name",
"role": "my-role",
"usernameKey": "username",
"passwordKey": "password"
}
CyberArk
The request body for a CyberArk credential path will be similar to:
{
"credentialPathName": "CyberCredentialPath",
"description": "Credential path description is optional",
"passwordVaultId": 1,
"credentialParameters": {
"queryString": "Safe=DevTest;Folder=Root;Object=postgres01"
}
}
Azure Key Vault
The request body for an Azure credential path will be similar to:
{
"credentialPathName": "AzureCredentialPath",
"description": "Credential path description is optional",
"passwordVaultId": 1,
"credentialParameters": {
"vaultName": "your-vault-name",
"usernameKey": "username",
"passwordKey": "password"
}
}
The vaultName
will be the name of the Azure Key Vault used and can be found in the Azure portal.
Google Cloud Platform
The request body for a GCP credential path will be similar to:
{
"credentialPathName": "GCPCredentialPath",
"description": "Credential path description is optional",
"passwordVaultId": 1,
"credentialParameters": {
"versionId": "latest",
"projectId": "example-project",
"usernameKey": "username",
"passwordKey": "password"
}
}
Every GCP credential value added to or changed in Secret Manager will be versioned. There are two ways to specify a target version in a credential path: with the versionId
key as shown above, or with both passwordVersionId
and usernameVersionId
. The global versionId
cannot be combined with the more specific keys. In most cases "latest"
will be desired since it points to the last added version, but specific versions represented by an integer can be targeted as well. Both “latest"
or the integer must be specified as a string.
The value for parameters "usernameKey"
and "passwordKey"
specify the names of the secrets saved in Google Secret Manager used to provide a username and password for database connection. A secret for each is required. The names of the secrets are unimportant as long as they correspond to the required login information. As an example, if a secret called "my_database_username"
is created in GCP with the appropriate value, then "my_database_username"
would be the value of the "usernameKey"
parameter in the credential path.
The project ID is a numeric value, not the name of the GCP project. The numeric value can be found in the path for each secret in the project. If one of the secrets is selected, the path appears in the UI, and will be formatted like this:
projects/999999999999/secrets/my_database_username
The numeric value following /projects
is the project ID.
Configuring the database connector
Database connectors can be configured to use a password vault through either the Continuous Compliance Engine UI or the APIs.
UI configuration
When creating or editing a Db2, MariaDB, MSSQL, MySQL, Oracle, PostgreSQL, YugabyteDB, CockroachDB, or Sybase database connector, select the Password Vault option from the Authentication Type dropdown and then select the required credential path from the Credential Path dropdown. If the Test Connection run succeeds, then it is complete.
API configuration
CredentialPathId
is an optional field when creating a DB2, MariaDB, MSSQL, MySQL, Oracle, PostgreSQL, YugabyteDB, CockroachDB, or Sybase database connector via the API. Setting this value to the id of an existing credential path object will result in the connector using password vaults to retrieve the credential. As an example:
{
"connectorName": "psql-connector",
"databaseType": "POSTGRES",
"environmentId": 1,
"host": "mpv-psql.mydb.co",
"port": 5432,
"databaseName": "postgres",
"schemaName": "public",
"credentialPathId": 1
}