envelope

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2019 License: MIT Imports: 14 Imported by: 1

README

Envelope Build Status

Envelope is a tool designed to help any project keep their secrets in version control cheaply and securely.

How it works

Envelope uses AWS KMS to generate and encrypt "data keys" that are stored in a keyring file and these data keys are used to encrypt / decrypt your data.

Since everything in the keyring file is encrypted it is safe to commit to version control.

All you will need to decrypt is sufficient IAM permissions, the keyring file and the secrets file(s).

Features:

  • "Profiles" which allow multiple data keys with differing KMS keys and encryption contexts
  • Recursive decryption of structured formats (YAML, JSON & TOML)
  • Blob based encryption / decryption for unstructured formats
  • Asymmetric encrypt / decrypt permissions using IAM policies on KMS encryption contexts (e.g. developers could encrypt production secrets but not decrypt)
  • Fine grained permissions using IAM policies on encryption contexts
  • "Encrypt in place" functionality for ease of use
  • Auditing of decryption key access using AWS CloudTrail w/ KMS

Installing

Grab an appropriate binary from the releases page or if you're on OSX brew install mikesimons/brew/envelope

First steps

In AWS go to IAM -> Encryption keys (bottom of left menu) and create a KMS key. Grab the full ARN of the key and use it in the place of <KMSARN> below. --context is optional but recommended to enable fine grained permissions:

envelope profile add --context="env=dev" dev awskms://<KMSARN>

This will create a file called keyring.yaml that you need to keep in version control.

Given the following configuration file in config.yaml:

myservice:
  database_username: user
  database_password: pass

You can run the following command to encrypt the password:

envelope encrypt --profile dev --key myservice.database_password --in-place config.yaml

This will write the encrypted value directly to the file. Check the limitations section for caveats around encrypting in-place.

It is also possible to encrypt entire files as blobs with envelope:

cat config.yaml | envelope encrypt --profile dev > config.yaml.enc

Or to set previously unset keys:

echo "somevalue" | envelope encrypt --profile dev --key my.new.key config.yaml

To see the decrypted values of these files:

envelope decrypt config.yaml

or

envelope decrypt --format=blob config.yaml.enc

Using the context provided when you add the key to the envelope keyring you can grant fine grained permissions using IAM. For example, the following policy will allow the given role to encrypt secrets for production but not decrypt them:

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::111122223333:role/MyRole"
  },
  "Action": "kms:Encrypt",
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "kms:EncryptionContext:env": "production"
    }
  }
}

You must take special care around providing decryption access to users with contexts. If you create a policy that allows users to decrypt without a context condition they will be able to decrypt ALL values.

Limitations

Numeric & boolean values will get converted to strings when processed by envelope

Due to the fact that the golang yaml parser will default all scalar values to strings when unmarshalling in to interface{} maps there is no way to avoid this right now.

Map keys will be lexicographically sorted in output when processed by envelope

Due to the fact that YAML & JSON marshallers internally use golang maps for k/v structures and golang maps have non-deterministic ordering of keys the marshallers will sort map keys when emitting marshalled output. This means that so does envelope.

Comments and formatting are stripped when processed by envelope

Since the structured parsers do not retain comment nor formatting information it is not currently possible to preserve these when processing files with envelope.

Similar projects

  • AWS Systems Manager Parameters
    • Stores and provides an API for configuration parameters with KMS support
    • Supports versioning of parameters but not storage in version control
  • SOPS
    • Uses envelope encryption to encrypt YAML data
    • Supports KMS & GPG
    • Wants to encrypt entire file by default & sign that data (making it difficult to merge)
  • credstash / unicreds
    • Uses dynamodb to store data encrypted with KMS
    • Supports versioning of parameters but not storage in version control
    • No specific support for structured data so everything encrypted as blobs

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Base64Encoder added in v0.1.0

func Base64Encoder(in []byte, buf io.Writer) error

func NopEncoder added in v0.1.0

func NopEncoder(in []byte, buf io.Writer) error

Types

type EncryptOpts added in v0.1.0

type EncryptOpts struct {
	Encoder    func([]byte, io.Writer) error
	WithPrefix bool
}

type Envelope

type Envelope struct {
	Keyring                  keyring.Keyring
	Prefix                   string
	StructuredErrorBehaviour func(error) (traverser.Op, error)
}

Envelope holds the configuration and keyring

func WithYamlKeyring

func WithYamlKeyring(path string) (*Envelope, error)

WithYamlKeyring initializes Envelope with a yaml file based keyring

func (*Envelope) AddKey

func (s *Envelope) AddKey(alias string, masterKey string, context map[string]string) (string, error)

AddKey will add the given key to the keyring with alias & context

func (*Envelope) Decrypt

func (s *Envelope) Decrypt(input io.Reader) ([]byte, error)

Decrypt will decrypt the input as a blob and return the decrypted value as a byte array

func (*Envelope) DecryptStructured

func (s *Envelope) DecryptStructured(input io.Reader, format string) ([]byte, error)

DecryptStructured will parse the input as format and use the encryption prefix to automatically identify and decrypt encrypted values

func (*Envelope) DecryptStructuredAsMap added in v0.1.0

func (s *Envelope) DecryptStructuredAsMap(input io.Reader, format string) (interface{}, error)

func (*Envelope) Encrypt

func (s *Envelope) Encrypt(alias string, input io.Reader) ([]byte, error)

Encrypt will encrypt the input as a blob using the key given and default options

func (*Envelope) EncryptWithOpts added in v0.1.0

func (s *Envelope) EncryptWithOpts(alias string, input io.Reader, opts EncryptOpts) ([]byte, error)

EncryptWithOpts will encypt the input as a blob using the key given and the options specified

func (*Envelope) InjectEncrypted added in v0.1.0

func (s *Envelope) InjectEncrypted(alias string, input io.Reader, key string, value io.Reader, format string) ([]byte, error)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL