Skip to main content

Keyring Manager Setup

The Keyring Manager is a command-line utility, packaged with the Universal Controller installer, that creates and rotates the Key Encryption Keys (KEKs) stored in your keyring file. The keyring file holds the master keys that wrap your Data Encryption Keys (DEKs) and encrypt sensitive values in the Controller's uc.properties configuration file.

A configured keyring is required to enable Data Encryption Keys.

The Keyring Manager is included in the Universal Controller installer packages:

  • universal-controller-n.n.n.n-build.n.zip
  • universal-controller-n.n.n.n-build.n.tar

When you unpack the installer, the Keyring Manager is at the root of the package: keyring-manager.sh (Linux) and keyring-manager.bat (Windows). Run it from there.

├── universal-controller-n.n.n.n-build.n.war
├── install-controller.sh
├── install-controller.bat
├── keyring-manager.sh
├── keyring-manager.bat
└── lib/
├── uc-install.jar
└── gson-2.12.1.jar
warning

The keyring file is the root of trust for the Controller's encryption. It holds the Key Encryption Keys (KEKs), which wrap every Data Encryption Key (DEK) in the database and also directly protect a small set of bootstrap secrets stored in uc.properties (database password, truststore/keystore passwords, DB secrets provider parameters, etc.). Through the DEKs, the KEKs transitively protect the credentials and secrets stored in the database.

Protect it accordingly:

  • Restrict read access to the operating system account that the Controller (Tomcat) runs as. No other user, group, or broad "everyone" entry should have access.
  • Restrict access to the parent directory as well, so that unauthorized accounts cannot list its contents or discover the keyring file's existence.
  • The Controller itself does not need write access to the file. Operators replace it only during key rotation.
  • Store the file outside of any web-accessible directory (such as the Tomcat webapps directory) and outside of source control or shared configuration repositories.
  • Place the file on an encrypted volume so that disk-level theft or copying does not expose it. Encryption at rest does not replace file-system permissions; it adds a second layer of protection.
  • Each Controller node in a cluster should maintain its own local copy of the keyring. Do not share it via a network mount.
  • Treat old keyring files as sensitive indefinitely. Past KEKs remain valuable as long as any older database backup or historical DEK exists.
  • Apply the same level of access control and protection to any backups of the keyring file as you do to the file itself.

Consult your operating system's documentation for the appropriate commands to set ownership, permissions, and encryption on the file and its parent directory.

Generating a Keyring

Use the Keyring Manager init command to create a new keyring file containing a single key, which is set as the primary KEK:

./keyring-manager.sh init --keyring /secure/path/keyring.json --description "Production controller"

This produces a keyring file similar to the following:

keyring.json
{
"primary": "550e8400e29b41d4a716446655440000",
"kek": {
"550e8400e29b41d4a716446655440000": {
"key": "BASE64_ENCODED_AES_KEY",
"created": "2025-01-20T14:45:00Z",
"description": "Production controller"
}
}
}

The primary field identifies the KEK currently used for new encryption. The kek object holds every KEK by its identifier. Each entry contains the base64-encoded AES key, its creation timestamp, and the description you supplied.

Configuring the Controller to Use the Keyring

Point the Controller at your keyring using one of the following (configure one, not both):

Property / VariableDescription
uc.keyring.filePath to keyring.json on the filesystem.
UC_KEYRING_BASE64 (environment variable)The base64-encoded contents of keyring.json. Useful for containerized deployments where mounting a file is impractical. Generate it with `cat keyring.json

Backing Up the Keyring

The Keyring Manager automatically backs up keyring.json before any modification. Backup files are written alongside the original with a timestamped name, for example keyring.json.1737394200000.backup.

warning

Backup files contain plaintext key material. Store them securely, and delete them once you have confirmed the new keyring is functional. Administrators are responsible for handling these backups appropriately and securely.

The Keyring Manager never removes old keys from the keyring. Removing a key is a manual administrative task, and you must only remove a key once no encrypted data still depends on it.

Rotating the Key Encryption Key

Rotating the KEK is a two-part process: first you add a new primary KEK to the keyring file with the Keyring Manager, then the Controller must load the updated keyring, either by reloading it on a running Controller or at startup.

Adding a New KEK

The 'rotate' command adds a new key to the keyring and sets it as the primary key:

./keyring-manager.sh rotate --keyring /secure/path/keyring.json --description "Production controller"

The keyring now contains both keys, with the new key set as the primary:

keyring.json
{
"primary": "8a3c1d4e2f5b6a7c9d0e1f2a3b4c5d6e",
"kek": {
"550e8400e29b41d4a716446655440000": {
"key": "BASE64_ENCODED_AES_KEY_1",
"created": "2025-01-20T14:45:00Z",
"description": "Production controller"
},
"8a3c1d4e2f5b6a7c9d0e1f2a3b4c5d6e": {
"key": "BASE64_ENCODED_AES_KEY_2",
"created": "2025-01-20T16:30:00Z",
"description": "Production controller"
}
}
}

After rotation, the new key is used for all new encryption, and the previous key is used only for decryption.

warning

Do not remove the previous primary KEK from the keyring. It is still required to decrypt your existing Data Encryption Keys until they have all been re-wrapped under the new primary KEK. Removing it prematurely will break decryption.

Reloading the Keyring

To apply an updated keyring to a running Controller without restarting it, run the Reload Keyring server operation. When the operation runs, the Controller:

  1. Loads the updated keyring file, replacing the keyring currently loaded by the Controller.
  2. Re-wraps every Data Encryption Key in the database under the new primary KEK.
  3. Re-encrypts all stored data records in a background process as a precautionary measure. Re-encryption of the data records is not strictly required, since the Data Encryption Keys themselves are unchanged, but it is performed to ensure consistency.

Two conditions must be met before the operation will run:

  • It must be run on the active cluster node. Passive nodes are rejected.
  • It must be the only live node in the cluster. If any other Controller node is online, the operation is blocked, because those nodes hold an outdated keyring and would fail to decrypt the re-wrapped Data Encryption Keys.
info

The Reload Keyring operation is only available when the keyring is provided as a file (uc.keyring.file).

Before running the operation, run the rotate command to add new key to the existing keyring file.

A corresponding RESTful web service is also available for this operation.

Reloading the Keyring in a Cluster

Because the Reload Keyring operation cannot run while other nodes are online, a rolling procedure is required:

Step 1Stop all passive Controller nodes.
Step 2Update keyring.json on the active node: add the new KEK, set it as the primary, and keep the previous primary KEK.
Step 3Run the Reload Keyring server operation on the active node. The keyring swap, Data Encryption Key re-wrap, and data re-encryption all run here.
Step 4Update keyring.json on every passive node with the same file.
Step 5Restart the passive nodes. Each reads the updated keyring at startup and loads the already-re-wrapped Data Encryption Keys from the database.

Sharing Keys Between Controllers

When you promote or import/export records between two Controllers, any KEK used to wrap a shared Data Encryption Key must be present in the keyring of every participating Controller.

For example, to share keys between a development and a production Controller, add the development KEK to the production keyring and the production KEK to the development keyring:

Development keyring.json
{
"primary": "8a3c1d4e2f5b6a7c9d0e1f2a3b4c5d6e",
"kek": {
"8a3c1d4e2f5b6a7c9d0e1f2a3b4c5d6e": {
"key": "BASE64_ENCODED_AES_KEY_1",
"created": "2025-01-20T14:45:00Z",
"description": "Development controller"
},
"0afc1bca99bd40f8b7db27b21e48a52d": {
"key": "BASE64_ENCODED_AES_KEY_2",
"created": "2025-01-20T18:30:00Z",
"description": "Production controller"
}
}
}
Production keyring.json
{
"primary": "0afc1bca99bd40f8b7db27b21e48a52d",
"kek": {
"0afc1bca99bd40f8b7db27b21e48a52d": {
"key": "BASE64_ENCODED_AES_KEY_2",
"created": "2025-01-20T18:30:00Z",
"description": "Production controller"
},
"8a3c1d4e2f5b6a7c9d0e1f2a3b4c5d6e": {
"key": "BASE64_ENCODED_AES_KEY_1",
"created": "2025-01-20T14:45:00Z",
"description": "Development controller"
}
}
}

After adding a KEK to a Controller's keyring, either restart the controller or run the Reload Keyring server operation to pick up the new key. For more on how keys and encrypted records move between Controllers, see Promotion and Import/Export.