The server components of Digipass S3 Authentication Software use secrets, such as keys and passwords, to access the following external services:
Databases
Push notification services
Private key for APNS (Private Key Operations)
Private key for Firebase Cloud Messaging (Private Key Operations)
App secret for Huawei Messaging Service
Google Play Integrity
Email servers
SMS API (Twilio)
Jumio PhotoID services
Digipass S3 Server components provide a programmatic interface in Java for you to develop a plugin to retrieve credentials that are managed externally. Digipass S3 Authentication Software allows you to store a password either as a handle to an external secrets manager using your Secrets plugin, or as an encrypted password.
Creating a Secrets plugin
You must implement the following Java interface for a Secrets plugin. Each server component creates a single instance of the class using the no-argument constructor at startup. There may be multiple threads fetching the secrets at the same time.
package com.noknok.secrets.spi;
/**
* Implement this interface to fetch passwords from a password vault
*
* The implementation class name should be provided as Java system property
* nnl.secrets.plugin.class.name
*/
public interface SecretsPlugin {
/**
* Called when a password is required by the relevant service. It
* may be called from multiple threads. Implementation can throw an
* RuntimeException if it is unable to fetch a password from the vault
*
* @param context context for the request
* @param secretHandle Handle that is configured for the password
* @return The actual password from the vault
*/
public String fetchSecret(SecretsContext context, String secretHandle);
}
/**
* This class defines the context, in other words, the name of the server property
* that represents a password. For example, mail.smtp.password and tenant ID.
*/
public class SecretsContext {
public SecretsContext(String name, String tenantId);
/**
* Returns the name of the context
*
* @return the name, e.g. "db.password", "mail.smtp.password",
* "clientSecret"
*/
public String getName();
/**
* Returns the id of the tenant
*
* @return the tenant ID, e.g., "Admin"
*/
public String getTenantId();
}Building the Secrets plugin
Follow these guidelines to implement your Secrets plugin:
Make sure you have access to a Digipass S3 Server installation for development and testing purposes.
Build your class that implements the SecretsPlugin interface with a dependency on nnl-secrets-spi-8.0.1-13.jar found inside the folder: <NNL_HOME>/admin/lib/thirdparty.
Package your plugin implementation into a jar file.
Configuring the Digipass S3 Server to use the Secrets Plugin
Step 1. Place a copy of the Secrets plugin implementation jar file, along with its third party dependencies, into all of the following directories:
tomcat/webapps/nnl/WEB-INF/lib/
tomcat/webapps/nnlgateway/WEB-INF/lib/
tomcat/webapps/nnladmin/WEB-INF/lib/
tomcat/webapps/nnlauthsvc/WEB-INF/lib/
tomcat/webapps/gwtutorial/WEB-INF/lib/
<NNL_HOME>/admin/lib/thirdparty/
Step 2. Assign the implementation class name to the environment variable NNL_SECRETS_PLUGIN_CLASS_NAME for the following components:
Tomcat: Inside the <TOMCAT_HOME>/bin/setenv.sh file, configure the plugin class name as in the example below:
export NNL_SECRETS_PLUGIN_CLASS_NAME=com.mycompany.SecretsPluginCommand-line utility: In the terminal where you run the Digipass S3 command-line utility, set the environment variable NNL_SECRETS_PLUGIN_CLASS_NAME as in the example below:
export NNL_SECRETS_PLUGIN_CLASS_NAME=com.mycompany.SecretsPluginStep 3. Optional. Configure handles for passwords. Note that when you implement a Secrets plugin, the administrator enters a handle to the password that is stored in the external secrets manager. But the administrator also has the option of storing passwords in the database in encrypted form.
For Tomcat web apps, edit tomcat/bin/setenv.sh and modify the environment variables to use your handles. Prefix {handle} to handles. For example, if the handle is password_handle, then set the value of the environment variable to {handle}password_handle.
export RUNTIME_DB_ENCRYPTED_PASSWORD={handle}<runtime.db.password_handle>For the command-line tool, go to <NNL_HOME>/admin/conf and manually update the files nnl-db.properties and application.properties. Configure the operational database password to be the handle with {handle} prefixed to the password.
Configure the aliases that work throughout the Digipass S3 Server, and ensure password rotation can be accomplished for different services.
For the Authentication Server and the Admin Console web apps, the database password is fetched only once from the external secrets manager - on server startup. For command-line operations, the database password is fetched each time you run a command.
Database password rotation requires a server restart so that the new password can be fetched using the same handle. If your company requires a new handle then please contact OneSpan Customer Support.
The table below shows the system-wide password that is fetched from the external secrets manager when using a handle. The class SecretsContext is defined in your Secrets plugin source code.
Password from external secrets manager for | SecretsContext |
|---|---|
Operational Database | name = db.password tenantId = SYSTEM |
Configure tenant-specific handles by using either the Admin Console or the command-line tool nnl-mgmt.sh. If you use the command-line tool, use the properties set command and prefix the literal "{handle}" to the handle from the external secrets manager. If for some service a handle is not available, then use the encrypted password.
The two tables below show tenant-specific handles that are fetched from the external secrets manager. The class SecretsContext is defined in your Secrets plugin source code.
For the services in this first table, the password is fetched from the external secrets manager once when the relevant push service is lazy-loaded on the server using the handle configured for the secret. To change your password, use the Admin Console or the command-line tool nnl-mgmt.sh to set the same handle to trigger the server to pick the new password from the external secrets manager. Password rotation does not require restarting the server.
Password from external secrets manager for | SecretsContext |
|---|---|
Push notification services | name = ios:<package_name>##oob.ios.apns.server.cert.password tenantId = your_tenant_id name = ios:<package_name>##oob.ios.apns.server.token.signing.key tenantId = your_tenant_id name = android:<package_name>##oob.android.server.key tenantId = your_tenant_id name = android:<package_name>##oob.hms.service.appsecret tenantId = your_tenant_id |
Private Key for APNS (Private Key Operations) | name = ios:<package_name>##oob.ios.apns.server.token.signing.key.secret tenantId = your_tenant_id |
Private key for Firebase Cloud Messaging (Private Key Operations) | name = android:<package_name>##oob.fcm.service.account.key.secret tenantId = your_tenant_id |
JWT Decryption Key for Google Play Integrity | name = <package name>##nnl.play.integrity.jwt.decryption.key tenantId = your_tenant_id |
JWT Verification Key for Google Play Integrity | name = <package name>##nnl.play.integrity.jwt.verification.key tenantId = your_tenant_id |
Service Account Key for Google Play Integrity | name = <package name>##nnl.play.integrity.service.account.key.secret tenantId = your_tenant_id |
For the services in this second table, the password is fetched from the external secrets manager each time you call the service for an authentication method-specific secret. Password rotation does not require a server restart if the handle remains the same.
Password from external secrets manager for | SecretsContext |
|---|---|
Email Servers | name = mail.smtp.password tenantId = your_tenant_id |
SMS API (Twilio) | name = twilio.auth.token tenantId = your_tenant_id |
Jumio PhotoID services | name = nv.api.secret tenantId = your_tenant_id |
If you need to change the handles from either of the above tables, please contact OneSpan Customer Support.
Step 4. Verify your Configuration.
Restart Tomcat and observe the logs. Verify that the Secrets plugin has been picked up by the runtime system. For example, in the Authenticator Server nnl.log you should see:
INFO [main]
com.noknok.secrets.spi.internal.SecretsPluginWrapper
loadSecretsPlugin -
Secrets plugin implementation configured on the server - com.mycompany.SecretsPluginPerform an authentication with FIDO OOB that uses push notifications, Email OTP, SMS OTP, and Photo ID. These operations fetch passwords from the external secrets manager. If the Secrets plugin is implemented and configured properly, these operations complete successfully.
Read on for installation instructions for your Secrets plugin in a Digipass S3 Server for production purposes.