constant

package module
v0.0.0-...-8494a9a Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2023 License: MIT Imports: 8 Imported by: 0

README

Constant

GoReport Badge SonarCloud Snyk

A secrets and parameter store that doesn't suck

Documentation

Index

Constants

View Source
const (
	NONCE_SIZE = 12 // Size of the nonce, in bytes, used for GCM
	KEY_SIZE   = 32 // Size of the key, in bytes, used for AES-256
)
View Source
const PATH_DELIMITER string = "/"

PATH_DELIMITER is the delimiter used to separate path elements.

Variables

View Source
var (
	WrappingMechanismName = map[int32]string{
		0: "WRAPPING_MECHANISM_UNSPECIFIED",
		1: "WRAPPING_MECHANISM_NONE",
		2: "WRAPPING_MECHANISM_INSECURE",
	}
	WrappingMechanismValue = map[string]int32{
		"WRAPPING_MECHANISM_UNSPECIFIED": 0,
		"WRAPPING_MECHANISM_NONE":        1,
		"WRAPPING_MECHANISM_INSECURE":    2,
	}
)

Enum value maps for WrappingMechanism

Functions

func Decrypt

func Decrypt(dst, key, nonce, ciphertext, additionalData []byte) ([]byte, error)

Decrypt decrypts ciphertext with the provided key and nonce using AES-GCM. To reuse ciphertext's storage for the decrypted output, use ciphertext[:0] as dst.

Even if the function fails, the contents of dst, up to its capacity, may be overwritten.

func Encrypt

func Encrypt(dst, key, nonce, plaintext, additionalData []byte) ([]byte, error)

Encrypt encrypts plaintext with the provided key and nonce using AES-GCM. To reuse plaintext's storage for the encrypted output, use plaintext[:0] as dst.

func NewGCM

func NewGCM(key []byte) (cipher.AEAD, error)

NewGCM returns a new AES cipher in Galois Counter Mode (GCM) using the provided 32-byte key.

If the key is not 32 bytes, NewGCM will return an error. The returned cipher will be AES-256.

func NewKey

func NewKey() ([]byte, error)

NewKey returns a new 32-byte key for use with AES-GCM.

func NewNonce

func NewNonce() ([]byte, error)

NewNonce returns a new 12-byte nonce for use with AES-GCM. Nonce must never be reused for a given key. It should be (96 bits / 8 bits per byte) = 12 bytes long according to and NIST SP 800-38D. This is to remain compatible with other implementations.

Types

type DataEncryptionKey

type DataEncryptionKey struct {
	Ciphertext       []byte            // Ciphertext encrypted using AES-GCM and a 256bit key. First [NONCE_SIZE] bytes are the nonce.
	KeyEncryptionKey *KeyEncryptionKey // KeyEncryptionKey is the key used to encrypt and decrypt the DataEncryptionKey.
}

DataEncryptionKey is a key used to encrypt and decrypt [Parameters]. A DataEncryptionKey is encrypted using a KeyEncryptionKey and attached to exactly one Parameter.

The Ciphertext is the encrypted DataEncryptionKey. The first NONCE_SIZE bytes are the nonce used during encryption. The remaining bytes are the actual ciphertext.

func (*DataEncryptionKey) Destroy

func (dek *DataEncryptionKey) Destroy()

type ID

type ID xid.ID

ID is a unique identifier used across Constant.

func IDFromBytes

func IDFromBytes(b []byte) (ID, error)

func IDFromString

func IDFromString(s string) (ID, error)

func NewID

func NewID() ID

func (ID) Bytes

func (id ID) Bytes() []byte

func (ID) LogValue

func (id ID) LogValue() slog.Value

func (ID) String

func (id ID) String() string

type KeyEncryptionKey

type KeyEncryptionKey struct {
	ID      ID      // ID uniquely identifies a KeyEncryptionKey.
	Key     []byte  // Key is the cryptographic key used to encrypt and decrypt [DataEncryptionKey]s. This is encrypted using a [Wrapper].
	Tenant  *Tenant // Tenant is the tenant that the KeyEncryptionKey belongs to.
	Wrapper Wrapper // Wrapper is the [Wrapper] used to encrypt and decrypt the KeyEncryptionKey.
}

KeyEncryptionKey is a key used to encrypt and decrypt [Parameters] by proxy of [DataEncryptionKey]s. A KeyEncryptionKey can be used to encrypt and decrypt any number of [Parameters]. By using [DataEncryptionKey]s, the KeyEncryptionKey can be rotated without having to re-encrypt all of the [Parameters], thus limiting the time that the [Parameters] are unencrypted and vulnerable.

During cryptographic operations, the KeyencryptionKey ensures that plaintext secrets are never exposed to the application and securely erased at the earliest time possible. This is accomplished by ... TODO: Finish this The only exception to the rule of not exposing secrets to the application is when the a Parameter is decrypted. In this case it is necessary to replace the ciphertext with the plaintext.

To allow for the seecure storage of the KeyEncryptionKey, it is encrypted using an upstream Key Management Service (KMS) through a Wrapper.

func (*KeyEncryptionKey) Decrypt

func (kek *KeyEncryptionKey) Decrypt(p *Parameter) (*Parameter, error)

Decrypt decrypts the p.DataEncryptionKey using the KeyEncryptionKey and then uses the resulting DataEncryptionKey to decrypt p.Content. Finally, p.Encrypted is set to false and the DataEncryptionKey is cleared.

The original ciphertext is overwritten with the plaintext.

func (*KeyEncryptionKey) Encrypt

func (kek *KeyEncryptionKey) Encrypt(p *Parameter) (*Parameter, error)

Encrypt generates a new DataEncryptionKey and uses it to encrypt p. The DataEncryptionKey is then encrypted using the KeyEncryptionKey and attached to p. Finally, p.Encrypted is set to true. If p is nil, an error is returned. If p.Encrypted is true, an error is returned. The original plaintext is overwritten with the ciphertext.

type Parameter

type Parameter struct {
	ID                ID                // ID uniquely identifies a parameter. Use of the ID should be limited to systems where a single unique key is required, such as with database primary keys. Generally, the [Path] should be used instead, or optionally in conjunction with the [Tenant].
	Path              Path              // Path is an identifier for a parameter that is unique within a [Tenant].
	Content           []byte            // Content is the value of the parameter.
	Tenant            *Tenant           // Tenant is the tenant that the parameter belongs to.
	Encrypted         bool              // Encrypted indicates whether the parameter's content is encrypted.
	DataEncryptionKey DataEncryptionKey // DataEncryptionKey is the key used to encrypt the parameter's content.
}

Parameter is a parameter stored within Constant.

type Path

type Path []string

Path is a path within Constant. They are used to identify parameters.

func NewPathFromString

func NewPathFromString(s string) (Path, error)

NewPathFromString returns a new Path from a string. If the string is empty, an error is returned. If the string does not start with PATH_DELIMITER, an error is returned.

func (Path) String

func (p Path) String() string

Return the path as a string.

type Principal

type Principal struct {
	ID            ID      // ID uniquely identifies a principal.
	Name          string  // Name is the name of the principal.
	PreferredName string  // PreferredName is the preferred name of the principal.
	Tenant        *Tenant // Tenant is the tenant that the principal belongs to.
}

Principal is a principal within Constant. They are entities that can interact with Constant, such as users or services. Principals are associated with tenants, and can be granted permissions to perform actions on entities within those tenants.

type Tenant

type Tenant struct {
	ID                      ID                // ID uniquely identifies a tenant.
	FriendlyName            string            // FriendlyName is a human readable name for the tenant.
	DefaultKeyEncryptionKey *KeyEncryptionKey // DefaultKeyEncryptionKey is the key used to encrypt parameters within the tenant by default.
}

Tenant is a tenant within Constant. They group parameters together and provide a logical separation between them.

type Wrapper

type Wrapper interface {
	ID() string                               // ID is the ID of the Wrapper. It is a string, and not an [ID] because it should match the unique identifier of the resource that is being wrapped. For a key in AWS KMS, this would be the ARN.
	Wrap([]byte) ([]byte, error)              // Wrap encrypts (wraps) the provided bytes using the Wrapper.
	Unwrap(*KeyEncryptionKey) ([]byte, error) // Unwrap decrypts (unwraps) the [KeyEncryptionKey] using the Wrapper.
	Mechanism() WrappingMechanism             // Mechanism is the mechanism used to wrap the [KeyEncryptionKey].
	Tenant() *Tenant                          // Tenant is the tenant that the Wrapper belongs to.
}

Wrapper is an interface for wrapping and unwrapping [KeyEncryptionKey]s. Implemenations may choose to securely cache, the cleartext keys so as to excessive calls to the upstream Key Management Service. The cache must not be exposed to the application or persisted to non-volatile storage in any way.

type WrappingMechanism

type WrappingMechanism int32

WrappingMechanism is the mechanism used to wrap and unwrap [KeyEncryptionKey]s.

const (
	WRAPPING_MECHANISM_UNSPECIFIED WrappingMechanism = 0
	WRAPPING_MECHANISM_NONE        WrappingMechanism = 1
	WRAPPING_MECHANISM_INSECURE    WrappingMechanism = 2 // Not for production use. Implementations encrypt and decrypt using a hardcoded key, cleartext keys injected into memory. Used for testing.
)

func (WrappingMechanism) LogValue

func (x WrappingMechanism) LogValue() slog.Value

func (WrappingMechanism) String

func (x WrappingMechanism) String() string

Jump to

Keyboard shortcuts

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