0.0.42 • Published 3 years ago

@matrixai/polykey v0.0.42

Weekly downloads
39
License
Apache-2.0
Repository
github
Last release
3 years ago

Polykey (library)

Overview

js-polykey is the library used in the distributed secret sharing PolyKey app. You can find the actual application here. A polykey node is comprised of one or many Vaults to store Secrets. These vaults are encrypted with keys derived from the master private key. Secrets always remain encrypted on disk and are only decrypted in memory. All you need to connect with and share secrets with another keynode on the same local area network is it's public key, poykey takes care of discovery. Once connected, you can securely share vaults with each other and polykey will ensure those vaults are synced.

PolyKey requires a public/private keypair for all crypto operations, this can be provided to a pre-initialized KeyManager instance before polykey is initialized or it can be generated (this is the default).

Class Dependencies

In order to better understand how the pieces of PolyKey fit together, use this dependency DAG as reference:

KeyManager

This class is responsible for managing the public and private keys as well as any crypto operations using those keys. The symmetric vault keys are also managed by this instance.

The KeyManager is able to be loaded separately to the PolyKey main class and then passed into PolyKey. This is useful for loading the keypair prior to initializing PolyKey.

Key Generation

The key manager class can generate new symmetric keys using key derivation and the loaded private key

Testing:

PolyKey uses jest to test:

Command Line Interface (CLI)

Here is a demo of the CLI on asciinema.

The PolyKey CLI exposes various git-style sub commands that can be used to manipulate the PolyKey node:

Usage looks like the following:

PolyKey also exposes a helpful alias, pk, to make typing out commands a little quicker:

If you ever get stuck, every sub command has a help flag:

Agent

With this command you can manipulate the polykey agent including starting/restarting/stopping the agent, creating/importing a new polykey node, and getting the agent status.

Example usage:

Note: Polykey also provides the ability to set an environment variable, PK_PATH, instead of specifying the node path with -np '~/NewPolykeyNode'

Keys

This command is used to interact with PolyKey's KeyManager. With this command you can generate new keys, list keys and more.

Example usage:

Vaults

The vaults sub command lets you manipulate vaults, e.g. to list the existing vaults, add a new vault or destroy an old vault.

Example usage:

Secrets

The secrets sub command lets you manipulate secrets in a specific vault such as adding new secrets, removing old secrets or modifying existing secrets. In addition, polykey can inject variables into a modified environment with the pk secrets env command.

Example usage:

Crypto

The crypto sub command allows you to perform asymmetric cryptography operations (sign/encrypt/verify/decrypt) on files using the loaded public/prvate keypair.

Example usage:

Verbosity

Polykey uses four different levels of verbosity (Debug, Info, Warn, Error). The verbosity level can be set by using -v in the Polykey CLI. By default, the verbosity level will be set to log Warn messages. The verbosity level can be decreased by accumulating '-v' flags.

To decrease the verbosity further, TODO: explain verbosity levels when it is implemented

Development

If js-polykey is not installed, for example when developing, it can be run from source from a few methods:

npm run polykey -- -h

This will run polykey from source. the -- in the command separates the subsequent arguments from the npm run command, and passes it to the program being run, in this case polykey:

$ npm run polykey -- -h

> @matrixai/polykey@0.0.37 polykey /home/user/.../js-polykey
> ts-node -r tsconfig-paths/register src/bin/polykey.ts "-h"

Usage: polykey [options] [command]

Options:
  -V, --version   output the version number
  -h, --help      display help for command

Commands:
  keys            manipulate keys
  secrets         manipulate secrets for a given vault
  vaults          manipulate vaults
  nodes           node operations
  gestalts        gestalt operations
  social          social commands
  crypto          crypto operations
  agent           control the polykey agent
  ca              certificate authority operations
  oauth           http oauth2 operations
  help [command]  display help for command

npm run build
node dist/bin/polykey.js -h

This is equivalent to the above, but instead, we run the built file directly using node:

$ node dist/bin/polykey.js
Usage: polykey [options] [command]

Options:
  -V, --version   output the version number
  -h, --help      display help for command

Commands:
  keys            manipulate keys
  secrets         manipulate secrets for a given vault
  vaults          manipulate vaults
  nodes           node operations
  gestalts        gestalt operations
  social          social commands
  crypto          crypto operations
  agent           control the polykey agent
  ca              certificate authority operations
  oauth           http oauth2 operations
  help [command]  display help for command

Build

npm run build

This will create a dist folder.

Proto Files

All .proto files are stored in the the src/proto directory. JavaScript and type definition files are build using the following command:

We use:

grpc_tools_node_protoc_ts@5.0.1

In package.json, this looks like (specifically locked):

"grpc_tools_node_protoc_ts": "5.0.1",

To generate the proto files:

protoc \
  --proto_path=src/proto/schemas \
  --plugin=protoc-gen-grpc="$(which grpc_node_plugin)" \
  --js_out=import_style=commonjs,binary:src/proto/js \
  --ts_out=grpc_js:src/proto/js \
  --grpc_out=grpc_js:src/proto/js \
  ./src/proto/schemas/*.proto

Builds the dependency graph

arkit ./src -o ./media/dependencies.png

typedoc --media ./media

Deployment

Deploying to AWS ECS:

First login to AWS ECR:

aws --profile=matrix ecr get-login-password --region ap-southeast-2 | docker login --username AWS --password-stdin 015248367786.dkr.ecr.ap-southeast-2.amazonaws.com

Proceed to build the container image and upload it:

repo="015248367786.dkr.ecr.ap-southeast-2.amazonaws.com" && \
build="$(nix-build ./release.nix --attr docker)" && \
loaded="$(docker load --input "$build")" && \
name="$(cut -d':' -f2 <<< "$loaded" | tr -d ' ')" && \
tag="$(cut -d':' -f3 <<< "$loaded")" && \
docker tag "${name}:${tag}" "${repo}/polykey:${tag}" && \
docker tag "${name}:${tag}" "${repo}/polykey:latest" && \
docker push "${repo}/polykey:${tag}" && \
docker push "${repo}/polykey:latest"