Documentation
¶
Overview ¶
Package model is the primary interface around a secrets file.
It implements the functions needed to create a secrets file, add secrets, rotate them, and export them.
Example ¶
Here are a few ways to use this package:
store := model.NewStore(kmsKeyID, encryptionContext)
store.Add(kmsClient, "secret", "password", "Password for nuclear launch")
store.Save("mysecrets.json")
store := store.Load("mysecrets.json")
store.Contains("secret") // true
store.Rotate(kmsClient, "secret", "new_password")
store.Export(formatter.Bash) // "SECRET='new_password'"
store.Save("mysecrets.json")
store := store.Load("mysecrets.json")
store.RotateKMSKey(kmsClient, newKMSKeyID)
store.Save("mysecrets_rotated.json")
Secret encryption ¶
For each secret, a data key is requested from AWS KMS.
The encryption context is sent along and is stored alongside the encrypted data key. The name of the secret is added to the context automatically under the key "Secret"
KMS returns the data key encrypted with the master key (stored on AWS servers) and the corresponding plaintext
That data key is used to encrypt one secret.
A random nonce is generated and nacl/secretbox is used for encryption.
Under the hood, secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages. The length of messages is not hidden.
Finally, the encrypted key, the random nonce and the encrypted secret are each stored in the model.
Secrets decryption ¶
For each secret, the encrypted data key, random nonce and encrypted secret are extracted from the model
A request is made to AWS KMS to decrypt the encrypted data key. At this stage the encryption context is authenticated and logged. The name of the secret is added to the context automatically under the key "Secret"
Using the key plaintext and random nonce, the secret is decrypted using nacl/secretbox.
Index ¶
- type Secret
- type Store
- func (s *Store) Add(client kms.Client, plaintext string, name string, description string) error
- func (s *Store) Contains(name string) bool
- func (s *Store) ExportPlaintext(client kms.Client) (chan formatter.Item, error)
- func (s *Store) Find(name string) *Secret
- func (s *Store) Rotate(client kms.Client, name string, newPlaintext string) error
- func (s *Store) RotateKMSKey(client kms.Client, newKMSKeyID string) error
- func (s *Store) Save(path string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Secret ¶
type Secret struct {
// Ciphertext contains the encrypted secret value, the plaintext nonce,
// along with the encrypted data key used for this specific secret.
// A versioning field is also added, currently only `EJK1`
Ciphertext string `json:"ciphertext"`
// Description is a free-form explanation of what the secret is used for.
// Common use cases include : how to rotate the secret, how it is used
// in the code, ...
Description string `json:"description"`
// Name is the name of the secret used during exporting.
// As such, by convention and for ease of use in bash scripts (for example),
// it must be comprised of lowercase characters, digits and underscores only.
// Moreover, it cannot start with a number.
Name string `json:"name"`
// contains filtered or unexported fields
}
Secret represents a given secret
type Store ¶
type Store struct {
// Name/value pair that contains additional data to be authenticated during
// the encryption and decryption processes that use the key. This value is logged
// by AWS CloudTrail to provide context around the data encrypted by the key.
//
// Note that changing this value requires re-encrypting every secret
// in the file, since KMS uses it as part of the decryption process.
EncryptionContext map[string]*string `json:"encryption_context"`
// KMSKeyID is an aws ID pointing to the master key used to encrypt the
// secrets in this file.
//
// This value can be a globally
// unique identifier, a fully specified ID to either an alias or a key, or
// an alias name prefixed by "alias/".
//
// Key ARN Example - arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
//
// Alias ARN Example - arn:aws:kms:us-east-1:123456789012:alias/MyAliasName
//
// Globally Unique Key ID Example - 12345678-1234-1234-1234-123456789012
//
// Alias Name Example - alias/MyAliasName
KMSKeyID string `json:"kms_key_id"`
// Secrets is a list of secrets
Secrets []*Secret `json:"secrets"`
// Version is the version of the JSON schema to use. For now there is only
// version 1.
Version int `json:"version"`
// contains filtered or unexported fields
}
Store represents a secrets file.
func Load ¶
Load takes a path to a secrets file and returns the contents of the file unmarshaled in the model.
func (*Store) Add ¶
Add adds a new secret to the store
Note that the name of the secret is automatically added to the encryption context under the key "Secret"
func (*Store) Contains ¶
Contains is a convenience wrapper to check for the existence of a given secret in the file.
func (*Store) ExportPlaintext ¶
ExportPlaintext deciphers all the secrets and publishes them to a channel for formatting.
func (*Store) Rotate ¶
Rotate changes the plaintext of a stored secret. A new data key is generated.
Note that the name of the secret is automatically added to the encryption context under the key "Secret"
func (*Store) RotateKMSKey ¶
RotateKMSKey re-encrypts all the secrets with the new given KMS key