This repository/package houses a TypeScript/JavaScript implementation of the cross-platform, language-agnostic SecureStore secrets specification. In particular, this library may be used for interacting with SecureStore secrets containers, providing an easy-to-use and idiomatic interface for loading SecureStore containers and decrypting/retrieving secrets from within your existing JavaScript codebase, and is compatible with both frontend (à la browser) and backend (à la node/bun) code (though you're most likely to use it on the backend).
This JS library is largely intended to be used alongside one of the SecureStore cli companion apps, used to create SecureStore values and manage (add/remove/update) the secrets stored therein. In this example, we'll be using the ssclient cli utility to create a new store.
Typical SecureStore usage begins by creating a new SecureStore "vault" (an encrypted secrets container) that will store the credentials (usually both usernames/access keys and passwords/api keys) that your app will need for one or more services. Begin by compiling or downloading and installing a copy of ssclient, the SecureStore companion cli.
While you can compile it yourself or manually download pre-built binaries for your platform, you might find it easiest to just install it with npm:
~> npm install --global @neosmart/ssclientafter which you can proceed with the following steps:
~> mkdir secure/
~> cd secure/
~> ssclient create --export-key secrets.key
Password: ************
Confirm Password: ************
# Now you can use `ssclient -p` with your password or
# `ssclient -k secrets.key` to get or set additional
# secrets with the same keys.Secrets may be added with your password or the equivalent encryption key file, and may be specified in-line as arguments to ssclient or more securely at a prompt by omitting the value when calling ssclient create:
# ssclient defaults to password-based decryption:
~> ssclient set aws:s3:accessId AKIAV4EXAMPLE7QWERT
Password: *********similarly:
# Use `-k secrets.key` to load the encryption key and
# skip the prompt for the vault password:
~> ssclient -k secrets.key set aws:s3:accessKey
Value: v1Lp9X7mN2B5vR8zQ4tW1eY6uI0oP3aS5dF7gH9jSecrets can be retrieved at the commandline with ssclient or programmatically with a SecureStore library for your development language or framework of choice.
This library contains the js/ts implementation of the SecureStore protocol. The SecureStore protocol was intentionally designed to maximize security and compatibility, as such, this library has no external dependencies and can be used either from source or by adding it via the npmjs registry:
npm install --save @neosmart/securestoreafter which you can use the library as follows:
import { SecretsManager } from "@neosmart/securestore";
const sman = await SecretsManager.fromFile("secure/secrets.json",
{ keyFile: "secure/secrets.key" });
// Retrieve and decrypt a specific secret
const s3AccessId = sman.get("aws:s3:accessId");
const s3AccessKey = sman.get("aws:s3:accessKey");
// List all available keys in the vault
for (const key of sman.keys()) {
console.debug(`* ${key}`);
}The SecretsManager.fromFile() and KeySource.fromKeyFile() methods and the { keyFile: string } AuthOptions variant are only available in the backend (when using with node or bun). If using this library from the web or in another environment, you'll need to manually load the store contents and then use SecretsManager.fromJSON() instead:
import { SecretsManager } from "@neosmart/securestore";
const vaultJson = "..."; // the contents of secure/secrets.json
const vaultKey = "..."; // the contents of secure/secrets.key
const sman = await SecretsManager.fromJSON(vaultJson,
{ key: vaultKey });Or, to decrypt with a password interactively:
import { SecretsManager } from "@neosmart/securestore";
const vaultJson = "..."; // the contents of secure/secrets.json
const sman = await SecretsManager.fromJSON(vaultJson,
{ password: "..." });While it is strongly recommended to only load secrets programmatically with the encryption key with the { keyFile: "path/to/secrets.key" } or { key: Uint8Array } (where key has been securely preloaded) so as to avoid hard-coding any secrets in your code by specifying the path to the encryption key created by ssclient via the --export-key flag or top-level ssclient export-key command, the alternative KeySource.fromPassword() and SecretsManager.fromXxx(..., { password: string }) interfaces are also available – this can be handy if you're developing an interactive tool using SecureStore, for example.
The SecureStore library provides a high-level interface for decrypting and accessing secrets stored in SecureStore v3 vaults.
The following types/classes/interfaces are exposed by this library:
The primary interface for interacting with an encrypted vault.
fromJSON(json, auth)— Universal Initializes the manager from a raw JSON string (the contents of the SecureStoresecrets.json).fromObject(data, auth)— Universal Initializes the manager from the pre-parsedVaultDatacontents ofsecrets.json.fromFile(path, auth)— Backend Only Asynchronously reads and decrypts a vault file from the disk.get(name)— Universal Retrieves and decrypts a specific secret by its key. Returnsnullif not found.keys()— Universal Returns an array with the names/keys of all secrets stored within the vault.
An abstraction for the credentials used to unlock a vault.
fromPassword(password)— Universal Derives decryption keys from the provided password. Primarily for interactive use.fromKey(key)— Universal Loads a "raw" master key, loaded from the SecureStore encryption key into aUint8Arrayor ASCII-armored string.fromKeyFile(path)— Backend Only Reads a master key from the filesystem directly.
The configuration object used during initialization to specify how vault decryption will take place:
| Property | Type | Env | Description |
|---|---|---|---|
password |
string |
Universal | Decrypt using a password string. |
key |
Uint8Array |
Universal | Decrypt using a raw binary key. |
keySource |
KeySource |
Universal | Decrypt using a pre-constructed KeySource instance. |
keyFile |
string |
Backend | Path to a file containing the decryption key. |
This library is implemented using the Web Crypto standard and does not perform any cryptography in the runtime or using JavaScript sources – all cryptographic primitives are implemented by the browser/runtime for security and performance. This library is currently - and for the foreseeable future - intentionally dependency-free. Please refer to the main (rust) SecureStore repo/implementation for any protocol-specific or crypto-related questions or matters.