Using the Proxy in a secure data store

Starting up the Proxy

The Oracle NoSQL Database Proxy can be started on a secure data store using the following steps.

  1. A secure proxy connection should be bootstrapped. Before you start up the proxy, you need to create a bootstrap user in the secure data store for the proxy to bootstrap its security connection. In SQL shell, the following command will create a bootstrap user for the proxy. See Developers Guide for getting started with SQL commands.
    sql-> CREATE USER <proxy_user> IDENTIFIED BY "<proxy_password>";
    where,
    • proxy_user is the user name.
    • proxy_password is the password for the proxy_user.

    Note:

    The default privilege is sufficient for a bootstrap user. It is not recommended to grant admin privilege or any other additional privileges to the bootstrap user.

    Note:

    Any user-supplied name can be given for the bootstrap user.

  2. Create a directory ./proxy where the proxy related files can be stored.
  3. Create a login file ./proxy/proxy.login for the bootstrap user with the following information in it.
    oracle.kv.auth.username=<proxy_user>
    oracle.kv.auth.pwdfile.file=proxy.passwd
    oracle.kv.transport=ssl
    oracle.kv.ssl.trustStore=client.trust
    where,
    • proxy.passwd is the file to store the password value of the proxy_user user.
    • client.trust is the certificate trust file obtained from the kvstore deployment.

    See Create users and configure security with remote access to know how to generate the proxy.passwd and client.trust files in kvstore client machine. In this case, the proxy runs as a kvstore client. These files must exist in order for the proxy.login to work properly.

  4. Create a certificate.pem file and key-pkcs8.pem file for the proxy and driver to configure and establish a secure communication. If the Java driver is used, the driver.trust file should also be generated. See Generating Certificate and Private Key for the Oracle NoSQL Database Proxy in the Security Guide.
  5. Use the following command to start up the proxy for a secure data store:
    java -jar lib/httpproxy.jar \ 
    -storeName <kvstore_name> \ 
    -helperHosts <kvstore_helper_host> \ 
    [-hostname <proxy_host>] \ 
    [-httpsPort <proxy_https_port>] \ 
    -storeSecurityFile proxy/proxy.login \ 
    -sslCertificate certificate.pem \ 
    -sslPrivateKey key-pkcs8.pem \ 
    -sslPrivateKeyPass <privatekey_password> \ 
    [-verbose true]
    where,
    • kvstore_name is the data store name obtained from the data store deployment. See ping.
    • kvstore_helper_host is the data store's helper host:port list obtained from the data store deployment. See Obtaining a KVStore Handle in the Java Direct Driver Developer's Guide.
    • proxy_host is the hostname of the machine to host the proxy service. If the proxy is to be accessed from machines other than the one on which it is started this should be the hostname of the machine running the proxy. This parameter is optional and defaults to localhost which means that the proxy will only be available from the machine running the proxy.
    • proxy_https_port is the port on which the proxy is watching for requests on its host machine. This is an optional parameter and defaults to 443.

      Note:

      Use of port 80 may require additional privileges, depending on your machine.
    • proxy.login is the security login file generated in the earlier step for accessing the secure kvstore.
    • certificate.pem is the certificate file generated in the previous step.
    • key-pkcs8.pem is the private key file generated in the previous step.
    • privatekey_password is the password for the encrypted key-pkcs8.pem file.

    Note:

    The proxy start-up only accepts private key file in PKCS#8 format. If your private key is already in PKCS#8 (start with -----BEGIN ENCRYPTED PRIVATE KEY----- or -----BEGIN PRIVATE KEY-----), you don't need any additional conversion. Otherwise, you can use OpenSSL to do the conversion.

The Oracle NoSQL Database Java Driver contains the jar files that enables an application to communicate with the Oracle NoSQL Database Proxy. You can connect to the proxy using the following steps.

  1. Create a user for the driver which is used by the application to access the data store through the proxy.
    sql-> CREATE USER <driver_user> IDENTIFIED BY "<driver_password>"
        sql-> GRANT READWRITE TO USER <driver_user>
    where, the driver_user is the username and driver_password is the password for the driver_user user. In this example, the user driver_user is granted readwrite role, which allows the application to perform only read and write operation. See Configuring Authorization in the Security Guide.

    Note:

    If the user needs to create, drop, or alter tables or indexes, the driver_user should be granted dbadmin role, which allows the application to perform DDL operations.
    sql-> GRANT DBADMIN TO USER <driver_user>
  2. Install the Oracle NoSQL Database Java Driver in the application's classpath and use the following code to connect to the proxy.
    String endpoint = "https://<proxy_host>:<proxy_https_port>";
    StoreAccessTokenProvider atProvider = 
        new StoreAccessTokenProvider("<driver_user>","<driver_password>".toCharArray());
    NoSQLHandleConfig config = new NoSQLHandleConfig(endpoint);
    config.setAuthorizationProvider(atProvider);
    NoSQLHandle handle = NoSQLHandleFactory.createNoSQLHandle(config);
    where,
    • proxy_host is the hostname of the machine to host the proxy service. This should match the proxy host you configured earlier.
    • proxy_https_port is the port on which the proxy is watching for requests on its host machine. This should match the proxy https port configured earlier.
    • driver_user is the driver username. This should match the user created in the previous step.
    • driver_password is the password of the driver user.
  3. Start-up the application program and set the driver.trust file's path to the Java trust store by using the following command. This is required as the proxy is already set up using the certificate.pem and key-pkcs8.pem files.
    java -Djavax.net.ssl.trustStore=driver.trust \
    -Djavax.net.ssl.trustStorePassword=<password of driver.trust> \
    -cp .:lib/nosqldriver.jar application_program

    The driver.trust contains the certificate.pem or rootCA.crt certificate. If the certificate certificate.pem is in a chain signed by a trusted CA that is listed in JAVA_HOME/jre/lib/security/cacerts, then you don't need to append Java environment parameter -Djavax.net.ssl.trustStore in the Java command.

The on-Premises configuration requires a running instance of the Oracle NoSQL database. In addition a running proxy service is required.

If running a secure store, a certificate path should be specified through the REQUESTS_CA_BUNDLE environment variable:

$ export REQUESTS_CA_BUNDLE=
<path-to-certificate>/certificate.pem:$REQUESTS_CA_BUNDLE
or borneo.NoSQLHandleConfig.set_ssl_ca_certs().
In addition, a user identity must be created in the store (separately) that has permission to perform the required operations of the application, such as manipulated tables and data. The identity is used in the borneo.kv.StoreAccessTokenProvider.
from borneo import NoSQLHandle, NoSQLHandleConfig
from borneo.kv import StoreAccessTokenProvider
#
# Assume the proxy is secure and running on localhost:443
#
endpoint = 'https://localhost:443'
#
# Create the AuthorizationProvider for a secure store:
#
ap = StoreAccessTokenProvider(user_name, password)
#
# create a configuration object
#
config = NoSQLHandleConfig(endpoint).set_authorization_provider(ap)
#
# set the certificate path if running a secure store
#
config.set_ssl_ca_certs(<ca_certs>)
#
# create a handle from the configuration object
#
handle = NoSQLHandle(config)

The on-Premises configuration requires a running instance of the Oracle NoSQL database. In addition a running proxy service is required. In this case, the Endpoint config parameter should point to the NoSQL proxy host and port location.

If running a secure store, a user identity must be created in the store (separately) that has permission to perform the required operations of the application, such as manipulating tables and data. If the secure server has installed a certificate that is self-signed or is not trusted by the default system CA, specify InsecureSkipVerify to instruct the client to skip verifying server's certificate, or specify the CertPath and ServerName that used to verify server's certificate and hostname.
import (
    "fmt"     
    "github.com/oracle/nosql-go-sdk/nosqldb"
    "github.com/oracle/nosql-go-sdk/nosqldb/httputil"
)
...cfg:= nosqldb.Config{
    Endpoint: "https://nosql.mycompany.com:8080",
    Mode:     "onprem",
    Username: "testUser",
    Password: []byte("F;0s2M0;-Tdr"),
    // Specify InsecureSkipVerify
    HTTPConfig: httputil.HTTPConfig{
        InsecureSkipVerify: true,
    },
    // Alternatively, specify the CertPath and ServerName
    // HTTPConfig: httputil.HTTPConfig{
    //     CertPath: "/path/to/certificate-used-by-server",
    //     ServerName: "nosql.mycompany.com", 
    // set to the "CN" subject value from the certificate
    // },
}
client, err:=nosqldb.NewClient(cfg)
iferr!=nil {
    fmt.Printf("failed to create a NoSQL client: %v\n", err)
    return
}
deferclient.Close()
// Perform database operations using client APIs.
// ...

Your application will connect and use a running NoSQL database via the proxy service.

To connect to the proxy in secure mode, in addition to communication endpoint, you need to specify user name and password of the driver user. This information is passed in Config#auth object under kvstore property and can be specified in one of 3 ways as described below.

You may choose to specify user name and password directly:
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const client = new NoSQLClient({
    endpoint: 'https://myhost:8081',
    auth: {
        kvstore: {
            user: 'John',
            password: johnsPassword
        }
    }
});
This option is less secure because the password is stored in plain text in memory.
You may choose to store credentials in a separate file which is protected by file system permissions, thus making it more secure than previous option, because the credentials will not be stored in memory, but will be accessed from this file only when login is needed. Credentials file should have the following format:

{
    "user":     "<Driver user name>",
    "password": "<Driver user password>"
}
Then you may reference this credentials file as following:
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const client = new NoSQLClient({
    endpoint: 'https://myhost:8081',
    auth: {
        kvstore: {
            credentials: 'path/to/credentials.json'
        }
    }
});
You may also reference credentials.json in the configuration file used to create NoSQLClient instance.
{
    "endpoint": "https://myhost:8081",
    "auth": {
        "kvstore": {
            "credentials": "path/to/credentials.json"
        }
    }
}
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const client = new NoSQLClient('/path/to/config.json');

Your application will connect and use a running NoSQL database via the proxy service.

To connect to the proxy in secure mode, in addition to communication endpoint, you need to specify user name and password of the driver user. This information is passed in the instance of KVStoreAuthorizationProvider and can be specified in any of the ways as described below.

You may choose to specify user name and password directly:
var client = new NoSQLClient(
    new NoSQLConfig
    {
        Endpoint = "https://myhost:8081",
        AuthorizationProvider = new KVStoreAuthorizationProvider(
            userName, // user name as string
            password) // password as char[]
    });
This option is less secure because the password is stored in plain text in memory for the lifetime of NoSQLClient instance. Note that the password is specified as char[] which allows you to erase it after you are finished using NoSQLClient.
You may choose to store credentials in a separate file which is protected by file system permissions, thus making it more secure than the previous option, because the credentials will not be stored in memory, but will be accessed from this file only when the login to the store is required. Credentials file should have the following format:
{
    "UserName": "<Driver user name>",
    "Password": "<Driver user password>"
}
Then you may use this credentials file as following:
var client = new NoSQLClient(
    new NoSQLConfig
    {
        Endpoint: 'https://myhost:8081',
        AuthorizationProvider = new KVStoreAuthorizationProvider(
            "path/to/credentials.json")
    });
You may also reference credentials.json in the JSON configuration file used to create NoSQLClient instance:
{
    "Endpoint": "https://myhost:8081",
    "AuthorizationProvider": {
        "AuthorizationType": "KVStore",
        "CredentialsFile": "path/to/credentials.json"
    }
}
var client = new NoSQLClient("/path/to/config.json");

Note that in config.json the authorization provider is represented as a JSON object with the properties for KVStoreAuthorizationProvider and an additional AuthorizationType property indicating the type of the authorization provider, which is KVStore for the secure on-premise store.

The Oracle NoSQL Database Spring Data SDK contains the files that enable a Spring Data application to communicate with the proxy.

Install the Java driver in the application's classpath. Use the following code to connect to the proxy.

The configuration Spring bean provides a NosqlDbConfig object. You can use the StoreAccessTokenProvider class with the username and password of the Oracle NoSQL Database cluster. The StoreAccessTokenProvider class configures the Spring Data Framework to connect and authenticate to a secure Oracle NoSQL Database store.

import com.oracle.nosql.spring.data.config.AbstractNosqlConfiguration;
import com.oracle.nosql.spring.data.config.NosqlDbConfig;
import com.oracle.nosql.spring.data.repository.config.EnableNosqlRepositories;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import oracle.nosql.driver.kv.StoreAccessTokenProvider;
 
@Configuration
 
@EnableNosqlRepositories
 
public class AppConfig extends AbstractNosqlConfiguration {
    @Bean
    public NosqlDbConfig nosqlDbConfig() {
        AuthorizationProvider authorizationProvider;
        authorizationProvider = new StoreAccessTokenProvider(user, password);
        return new NosqlDbConfig("http://<proxy_host:proxy_http_port>", authorizationProvider);
    }
}
where,
  • proxy_host is the hostname of the machine to host the proxy service.
  • proxy_http_port is the port on which the proxy is watching for requests on its host machine.