-
Notifications
You must be signed in to change notification settings - Fork 2
Vault Service
AccountManager is able to encipher data using persistent symmetric or asymmetric keys, or specified secrets. By design, these keys are stored in the database. In addition, a convenience utility is provided to manipulate key stores for filesystem-based key persistence. The Vault Service provides a mechanism to protect those keys and/or that data with a key stored outside of the database, and which is protected with a secondary secret. Data protected by the vault service is recoverable when the database and the filesystems where the vault and and secret are stored are accessible.
Once a vault is created, it may be be used by the owner or shared (sharing a vault does not authorize access to the protected data), and can be used easily to further protect data at minimal impact to end user experience.
At present, vaults can only be created and updated using AccountManagerConsole due necessary file system operations outside the context of the web application.
Vaults are associated with a specific AccountManager user, are given a name that is unique to that user, and associated with two different file system paths. The first path is the location of the vault keys. The second path is the location of the encrypted credential used to decrypt the vault key.
The following command is used to create a new vault:
java -jar AccountManagerConsole.jar -organization /FirstContact -username test@foo.bar -password password -vault -action create -name triage -path /path/to/vault -credential /path/to/credential/triage.credential.json
There is no restriction to the number of vaults that can be created, but the name must be unique with respect to the owner.
The following artifacts are created for each vault:
- A DataType object named for the vault, located in a group named .vault under the owner's logical home directory
- This data includes the public vault key, and enciphered references to the private vault and credential key locations on the file system.
- A GroupType object named for the vault, located below the .vault group.
- Zero or more DataType objects below the named vault group, each representing a rotating cipher associated with the vault. Each instantiation of the VaultService, or on demand, or after a configurable number of operations, will cycle a new symmetric cipher.
- The vault key, located on the file system, is the enciphered private key.
- The credential file, located on the file system, is the enciphered secret used to access the vault key.
Vaults can be listed by viewing the data of a particular user's vault directory, assuming the requester has access. In particular, the urn reference is primarily used for internal vault references. The following example demonstrates how to list the vault from the console.
java -jar AccountManagerConsole.jar -organization /FirstContact -username test@foo.bar -password password -vault -action
The result is: triage (am:data:firstcontact:data:home.testfoo.bar..vault:dhjpywdl) where the urn is in the parenthesis.
From the example UI, the same information can be discovered by finding the group, and then listing the data in the group.
/// Find the vault group
var oVaultGroup = AM6Client.find("GROUP","DATA","/Home/test@foo.bar/.vault");
/// Fetch the first 10 results
var aVaultList = AM6Client.list("DATA",oVaultGroup.objectId,0,10);
A vault urn value can be obtained from the command line using the following shell scripts.
First, authenticate to obtain an access token:
./auth.sh /Organization username password
Second, get a specific vault urn by name:
./getVaultUrn.sh /Organization username vaultName
Note: getVaultUrn.sh will retrieve the entire vault data object and then extract the urn value from that object. The cached object will include the public key in the dataBytesStore value.
Data may be protected with the vault several ways. The easiest way is to the console to import data and designate it to be vaulted, or set the urn of a vault on a DataType object prior to adding or updating it through the REST service.
The following demonstrates how the console application can be used to import data and protect it with a designated vault.
java -jar AccountManagerConsole.jar -organization /FirstContact -username test@foo.bar -password password -importData "/path/to/local/files" -path "~/Data" -vault -urn "am:data:firstcontact:data:home.testfoo.bar..vault:dhjpywdl"
The -path value will be emitted as needed, so long as it is in an authorized location for the user. For large files, a special flag exists, -pointer, which comes with a number of restrictions. Specifying -pointer will store the path to the file, but not the file contents itself. However, due to the security implications of having this type of capability, data created as a pointer can only be read or deleted through the REST service.
Using the demo UI as a starting point, use the included or your preferred JavaScript console to execute the following script to find a vault urn, create a new data object, and add that data object.
/// Find the vault group
var oVaultGroup = AM6Client.find("GROUP","DATA","/Home/test@foo.bar/.vault");
/// Get a named vault in the vault group
var oVault = AM6Client.getByName("DATA", oVaultGroup.objectId, "triage");
/// Create a new data object
var oDataGroup = AM6Client.find("GROUP", "DATA", "~/Data");
var sTextData = "The message to protect.";
var oData = new org.cote.objects.dataType();
oData.name = "Test data";
oData.blob = true;
oData.groupPath = oDataGroup.path;
oData.nameType = "DATA";
oData.dataBytesStore = uwm.base64Encode(sTextData);
oData.mimeType = "text/plain";
oData.description = "";
oData.createdDate = new Date();
oData.modifiedDate = oData.createdDate;
oData.expiryDate = oData.createdDate;
oData.vaulted = true;
oData.vaultId = oVault.urn;
var bUpdated = AM6Client.update("DATA", oData);
Next time you read the data, you will see that another property has been set on the object: keyId. The keyId was an on-demand created cipher created to protect this data object, which is encrypted with the specified vault public key. To access the data, the vault private key is deciphered with the vault secret and used to decrypt the data key, which in turn is used to decipher the data blob value. From the end-user perspective, though, it's transparent.
var oDataGroup = AM6Client.find("GROUP", "DATA", "~/Data");
var oData = AM6Client.getByName("DATA", oDataGroup.objectId, "Test data");