Managing stores of secret things.
Writing deployment scripts is a critical yet error-prone activity which we would rather do in Haskell. One of the most difficult aspect of deployment scripts is the management of credentials: they cannot be stored in the VCS like almost everything else, but need to be organised and accessed while under lock and key. This is the problem that keystore is trying to solve: flexible, secure and well-typed deployment scripts.
All Haskell
This package is written purely in Haskell and all of the cryptographic packages it relies upon are written in Haskell.
JSON Format
It stores everything in a JSON format that has proven to be stable. We can can use migrations in future should the store need to be reorganized.
Simple and Flexible Underlying Model
Named Keys: every key has an name within the store that is associated with some secret data. If the secret data for that key is to be stored then it must identify another key in the store that will be used to encrypt the data. (Some keys -- the passwords -- will typically be auto-loaded from environment variables.)
*Functional model*: keys can be deleted and added again but the design encourages the retention of the history. The old keys remain available but deployment scripts will naturally select the latest version of a key. When a key is rotated this merely loads a new generation for the rotated key.
Simple Metadata: oher information, such as the identity of the key with its originating system (e.g., the identifier of an AWS IAM key) and some arbitrary textual information (the
comment
) may be associated with a key and accessible without recourse to the key or password needed to access the secret information.PKS: the seret may be a RSA provate key with the public key stored separately in the cler.
*MFA*: a secret may be protected with multiple named keys, all of which will be needed to recover the secret text.
Hashing: all keys can be hashed with an appropriate PBKDF-2 function and the hashes stored in the clear. These hashes may be sued to verify passwords but also can be inserted directly into configuration files for deployment. Precise control of the PBKDF-2 hash paramers is avaiable.
Hierarchical Organization: keys can be stored in different sections with each key being protected by a master key for that section. Sections can be configured to store the master keys of other sections thereby gaining acces to all of the keys in those sections and the keys they have access to.
Systems Integration: keys can automatically loaded from Environment variables. Typically a keystore session will start by settingb up an environment variable for the deployment section corresponding for the node that you need to deploy to. This will provide access to precisely the keys whose secrets you need to carry out the deployment and no more. It only needs access to the hashes of admin keys then they can be placed in separate higher-level
admin
sections. Provided care is taken preparing the environment you will not deploy to the wrong host (e.g., a live server rather than a staging server, or the wrong live server) because those keys will not be accessible.Configuration Control: the parameters controling the encryption and hashing functions can be set up independently in each section of the store, allowing for heavier hashing to be used on live servers and light hashing to be used on development and staging servers where authentication needs to be quick.
Keystore Integrity: the keystore can be signed and every operation made to check that the keystore matches its signature (and the public signing key matches an independent copy on the client).
External Crypto Operations: keys in the keystore can be used to sign or encrypt external obejcts (provided they can be loaded into memory).
The Layers
The keystore package has several layers. Most users will probably need only the top "batteries-included" layer:
Data.KeyStore.Sections
: this provides a high-level model that allows a flexible hierarchical keystore to be set up relatively easily. See thedeploy
example for details.Data.KeyStore.CLI
: This provides a stanalone program for inspecting and editing your keystores. It can also be embedded into your own deployment app. See thedeploy
example for details.Data.KeyStore.PasswordManager
provides a password manager which each user can use to setup their own local password store for holding the deployment passwords and session tokens used to autheticate the server.Data.KeyStore.IO
: this library provides general programatic access to a keystore throughIO
primitives. See the source code for theSections
for an example of this module in use.Data.KeyStore.KS
: this library provides general programatic access to a keystore through functionalKS
primitives. See the source code for theIO
for an exteded example this system in action.Data.KeyStore.Types
: This provides access to keystores at the types level.
Launch Instructions
See the bottom README on GitHub home page for launch instructions for the deploy example.