The Matrix AI team has been developing Polykey, a distributed peer-to-peer secret sharing system. It is intended to manage secrets, passwords, API keys for both humans and machines.
Many secret management systems have been designed either only for humans, or only for machines. We think this is unnecessary and intend Polykey to work in both cases. However for this article, we'll focus solely on what Polykey provides to the Matrix infrastructure.
Matrix Automatons may require secrets in order to communicate to an external API. There are several challenges to managing infrastructural secrets:
- How to automatically deploy software which relies on external API keys?
- How to manage key updates while there are online applications using and depending on those keys?
- How to ensure the security of the keys at-rest or during transit?
- How to revoke access keys?
- How to only pass keys that are strictly relevant for the application? (Principle of Least Privilege)
- How to backup keys?
Polykey was created to solve these problems and more. It integrates Git, public key cryptography and Keybase. It is designed to operate in a distributed manner similar to Git repositories (and using Git gives us version control for free). Here we will illustrate the abstract semantics of Polykey and in later articles we will address how we are implementing it.
A Polykey keynode is a single file. Keynodes can be stored anywhere. In this way, it is similar to
pass (https://www.passwordstore.org/). A keynode stores a set of secrets. Each secret is independently version controlled (this is where
Git comes in). Each secret or subset of secrets can be shared to another keynode. You can create multiple keynodes and make some keynodes only store subsets of other keynodes. Sharing can be either push-based or pull-based (just like
Git). For keynode A to push or pull secrets to or from keynode B, node A must have the capability to do so. This is done via public key cryptography.
In this way, a network of keynodes can represent a delivery mechanism for updating secrets. The computation required for dealing with secrets such as crytographic calculations or network transmission is divorced from where the secrets are stored. Furthermore read-only computations only require read-only access.
Because keynodes are just files, they are completely self-hosted and self-contained, and you can be sure that your secrets are encrypted at-rest and during transit. They are also constructed using standard Unix formats:
git repositories, GnuPG encryption, Unix hardlinks, and just Plain Text. You don't need to launch a service or bind to some network. Secrets can just be acquired using a command line program, or directly accessed via a standard libraries that understand Unix file formats. This makes the Polykey keynode format very flexible and amenable to automation.
The exact design of Polykey is still under flux, but you can follow along here: https://github.com/MatrixAI/Polykey
We have been developing several libraries to support the development:
- js-resource-counter - https://github.com/MatrixAI/js-resource-counter - Sequentially Allocatable and Deallocatable Resource Counter
- js-permaproxy - https://github.com/MatrixAI/js-permaproxy - Proxy pattern for proxying an object mediated through a container.
- js-virtualfs - https://github.com/MatrixAI/js-virtualfs - Virtual posix-like filesystem that runs completely in-memory.
- js-reference-pointer - https://github.com/MatrixAI/js-reference-pointer - Wrap a primitive value in a reference pointer, and pass by reference!
- js-object-tagger - https://github.com/MatrixAI/js-object-tagger - Takes a POJO and tags specified keys pointing to objects with unique numbers.
- js-array-fixed - https://github.com/MatrixAI/js-array-fixed - Arrays with Fixed Preallocated Length
- js-tree-order-index - https://github.com/MatrixAI/js-tree-order-index (not yet working) - Indexing Trees for Efficient Queries and Updates
- js-virtualgit - https://github.com/MatrixAI/js-virtualgit (not yet working) - In-memory Git