secrets

package module
v0.0.0-...-83e3fcc Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2022 License: MIT Imports: 30 Imported by: 0

README

Secrets

Secrets is an adapter to abstract the differences between different secrets backends so you can interact with them using a consistent interface.

Interfaces

Interfaces exposed by Secrets are:

SecretsStorage - Responsible for storing secrets, eg vault, AWS SSM, AWS Secrets Manager, Kubernetes Secrets, ENV variables, files, etc.

SymmetricKeyProvider - an abstraction of a key service that provides key-encryption-as-a-service. Implementations will be able to generate keys for an app to encrypt and decrypt data, then be able to return the key again at a later time having only a key id. This is an abstraction of services like AWS KMS, with implementations for Vault, and a "Native" implementation in Go that uses SecretStorage as a storage backend.

Encryption

Usage Example

using the vault secret provider

  vault, err := secrets.NewVaultSecretProviderFromConfig(secrets.VaultConfig{
		TransitMount: "/transit",
		SecretMount:  "/secret",
    Token:        "xxx123",
    Namespace:    "namespace",
		Address:      "https://vault",
	})
	if err != nil {
    return err
  }

  err = vault.SetSecret("password", "fried chicken")
	if err != nil {
    return err
  }
  
  secret, err = vault.GetSecret("password")
 	if err != nil {
    return err
  }
  // secret == "fried chicken"

Using the native key provider with the file secret provider.

  secretProvider := secrets.NewFileSecretProviderFromConfig(FileConfig{
		Path: os.TempDir(),
	})

	kp := secrets.NewNativeKeyProvider(secretProvider)

	key, err := kp.GenerateDataKey("rootKeyID")
	if err != nil {
    return err
  }

  // Save a copy of the encrypted key somewhere
  encryptedKey := key.Encrypted
  // We can later fetch it again from the service with:
  key, err = kp.DecryptDataKey("rootKeyID", encryptedKey)

	secretMessage := "toast"

	encrypted, err := secrets.Seal(key, []byte(secretMessage))
	if err != nil {
    return err
  }

	orig, err := secrets.Unseal(key, encrypted)
	if err != nil {
    return err
  }

  // orig == "toast"

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AlgorithmAESGCM = "aesgcm"
View Source
var DefaultVaultAlgorithm = "aes256-gcm96"
View Source
var ErrNotFound = fmt.Errorf("secret not found")
View Source
var ErrNotImplemented = errors.New("not implemented")
View Source
var SecretStorageProviderKinds = []string{
	"vault",
	"awsssm",
	"awssecretsmanager",
	"kubernetes",
	"env",
	"file",
	"plaintext",
}
View Source
var SymmetricKeyProviderKinds = []string{
	"vault",
	"awskms",
	"native",
}

Functions

func GetSecret

func GetSecret(name string, storage map[string]SecretStorage) (string, error)

GetSecret implements the secret definition scheme for Infra. eg plaintext:pass123, or kubernetes:infra-okta/clientSecret it's an abstraction around all secret providers

func GetSecretRaw

func GetSecretRaw(name string, storage map[string]SecretStorage) ([]byte, error)

func Seal

func Seal(key *SymmetricKey, plain []byte) ([]byte, error)

Seal encrypts plaintext with a decrypted data key and returns it in base64

func SealRaw

func SealRaw(key *SymmetricKey, plain []byte) ([]byte, error)

SealRaw encrypts plaintext with a decrypted data key and returns it in a raw binary format

func SetSecret

func SetSecret(name, value string, storage map[string]SecretStorage) error

func Unseal

func Unseal(key *SymmetricKey, encoded []byte) ([]byte, error)

Unseal decrypts base64-encoded ciphertext with a decrypted data key

func UnsealRaw

func UnsealRaw(key *SymmetricKey, encrypted []byte) ([]byte, error)

UnsealRaw decrypts ciphertext with a decrypted data key and returns a raw binary format

Types

type AWSConfig

type AWSConfig struct {
	Endpoint        string
	Region          string
	AccessKeyID     string
	SecretAccessKey string
}

type AWSKMSConfig

type AWSKMSConfig struct {
	AWSConfig `mapstructure:",squash"`

	EncryptionAlgorithm string `mapstructure:"encryptionAlgorithm"`
}

func NewAWSKMSConfig

func NewAWSKMSConfig() AWSKMSConfig

type AWSKMSSecretProvider

type AWSKMSSecretProvider struct {
	AWSKMSConfig
	// contains filtered or unexported fields
}

func NewAWSKMSSecretProvider

func NewAWSKMSSecretProvider(kmssvc kmsiface.KMSAPI) (*AWSKMSSecretProvider, error)

func NewAWSKMSSecretProviderFromConfig

func NewAWSKMSSecretProviderFromConfig(cfg AWSKMSConfig) (*AWSKMSSecretProvider, error)

func (*AWSKMSSecretProvider) DecryptDataKey

func (k *AWSKMSSecretProvider) DecryptDataKey(rootKeyID string, keyData []byte) (*SymmetricKey, error)

func (*AWSKMSSecretProvider) GenerateDataKey

func (k *AWSKMSSecretProvider) GenerateDataKey(rootKeyID string) (*SymmetricKey, error)

type AWSSSM

type AWSSSM struct {
	AWSSSMConfig
	// contains filtered or unexported fields
}

AWSSSM is the AWS System Manager Parameter Store (aka SSM PS)

func NewAWSSSM

func NewAWSSSM(client *ssm.SSM) *AWSSSM

func NewAWSSSMSecretProviderFromConfig

func NewAWSSSMSecretProviderFromConfig(cfg AWSSSMConfig) (*AWSSSM, error)

func (*AWSSSM) GetSecret

func (s *AWSSSM) GetSecret(name string) (secret []byte, err error)

GetSecret must have permission secretsmanager:GetSecretValue kms:Decrypt - required only if you use a customer-managed Amazon Web Services KMS key to encrypt the secret

func (*AWSSSM) SetSecret

func (s *AWSSSM) SetSecret(name string, secret []byte) error

SetSecret must have the secretsmanager:CreateSecret permission if using tags, must have secretsmanager:TagResource if using kms customer-managed keys, also need: - kms:GenerateDataKey - kms:Decrypt

type AWSSSMConfig

type AWSSSMConfig struct {
	AWSConfig
	KeyID string // KMS key to use for decryption
}

type AWSSecretsManager

type AWSSecretsManager struct {
	AWSSecretsManagerConfig
	// contains filtered or unexported fields
}

func NewAWSSecretsManager

func NewAWSSecretsManager(client *secretsmanager.SecretsManager) *AWSSecretsManager

func NewAWSSecretsManagerFromConfig

func NewAWSSecretsManagerFromConfig(cfg AWSSecretsManagerConfig) (*AWSSecretsManager, error)

func (*AWSSecretsManager) GetSecret

func (s *AWSSecretsManager) GetSecret(name string) (secret []byte, err error)

GetSecret must have permission secretsmanager:GetSecretValue kms:Decrypt - required only if you use a customer-managed Amazon Web Services KMS key to encrypt the secret

func (*AWSSecretsManager) SetSecret

func (s *AWSSecretsManager) SetSecret(name string, secret []byte) error

SetSecret must have the secretsmanager:CreateSecret permission if using tags, must have secretsmanager:TagResource if using kms customer-managed keys, also need: - kms:GenerateDataKey - kms:Decrypt

type AWSSecretsManagerConfig

type AWSSecretsManagerConfig struct {
	AWSConfig

	UseSecretMaps bool // TODO: support storing to json maps if this is enabled.
}

type EnvSecretProvider

type EnvSecretProvider struct {
	GenericConfig
}

func NewEnvSecretProviderFromConfig

func NewEnvSecretProviderFromConfig(cfg GenericConfig) *EnvSecretProvider

func (*EnvSecretProvider) GetSecret

func (fp *EnvSecretProvider) GetSecret(name string) (secret []byte, err error)

func (*EnvSecretProvider) SetSecret

func (fp *EnvSecretProvider) SetSecret(name string, secret []byte) error

type FileConfig

type FileConfig struct {
	GenericConfig
	Path string
}

type FileSecretProvider

type FileSecretProvider struct {
	FileConfig
}

func NewFileSecretProviderFromConfig

func NewFileSecretProviderFromConfig(cfg FileConfig) *FileSecretProvider

func (*FileSecretProvider) GetSecret

func (fp *FileSecretProvider) GetSecret(name string) (secret []byte, err error)

func (*FileSecretProvider) SetSecret

func (fp *FileSecretProvider) SetSecret(name string, secret []byte) error

type GenericConfig

type GenericConfig struct {
	Base64           bool
	Base64URLEncoded bool
	Base64Raw        bool
}

type KubernetesConfig

type KubernetesConfig struct {
	Namespace string
}

func NewKubernetesConfig

func NewKubernetesConfig() KubernetesConfig

type KubernetesSecretProvider

type KubernetesSecretProvider struct {
	KubernetesConfig
	// contains filtered or unexported fields
}

func NewKubernetesSecretProvider

func NewKubernetesSecretProvider(client *kubernetes.Clientset, namespace string) *KubernetesSecretProvider

func NewKubernetesSecretProviderFromConfig

func NewKubernetesSecretProviderFromConfig(cfg KubernetesConfig) (*KubernetesSecretProvider, error)

func (*KubernetesSecretProvider) GetSecret

func (k *KubernetesSecretProvider) GetSecret(name string) (secret []byte, err error)

func (*KubernetesSecretProvider) SetSecret

func (k *KubernetesSecretProvider) SetSecret(name string, secret []byte) error

Use secrets when you don't want to store the underlying data, eg secret tokens

type NativeKeyProvider

type NativeKeyProvider struct {
	SecretStorage SecretStorage
}

func NewNativeKeyProvider

func NewNativeKeyProvider(storage SecretStorage) *NativeKeyProvider

func (*NativeKeyProvider) DecryptDataKey

func (n *NativeKeyProvider) DecryptDataKey(rootKeyID string, keyData []byte) (*SymmetricKey, error)

func (*NativeKeyProvider) GenerateDataKey

func (n *NativeKeyProvider) GenerateDataKey(rootKeyID string) (*SymmetricKey, error)

type PlainSecretProvider

type PlainSecretProvider struct {
	GenericConfig
}

func NewPlainSecretProviderFromConfig

func NewPlainSecretProviderFromConfig(cfg GenericConfig) *PlainSecretProvider

func (*PlainSecretProvider) GetSecret

func (fp *PlainSecretProvider) GetSecret(name string) (secret []byte, err error)

func (*PlainSecretProvider) SetSecret

func (fp *PlainSecretProvider) SetSecret(name string, secret []byte) error

type SecretStorage

type SecretStorage interface {
	// Use secrets when you don't want to store the underlying data, eg secret tokens
	SetSecret(name string, secret []byte) error
	GetSecret(name string) (secret []byte, err error)
}

SecretStorage is implemented by a provider if the provider gives a mechanism for storing arbitrary secrets.

type SymmetricKey

type SymmetricKey struct {
	Encrypted []byte `json:"key"`  // the encrypted data key. To be stored by caller.
	Algorithm string `json:"alg"`  // Algorithm key used for encryption. To be stored by caller.
	RootKeyID string `json:"rkid"` // ID of the root key used to encrypt the data key on the provider. To be stored by caller.
	// contains filtered or unexported fields
}

type SymmetricKeyProvider

type SymmetricKeyProvider interface {
	// GenerateDataKey makes a data key from a root key id: if "", a root key is created. It is okay to generate many data keys.
	GenerateDataKey(rootKeyID string) (*SymmetricKey, error)
	// DecryptDataKey decrypts the encrypted data key on the provider given a root key id
	DecryptDataKey(rootKeyID string, keyData []byte) (*SymmetricKey, error)
}

SymmetricKeyProvider is implemented by a provider that provides encryption-as-a-service. Its use is opinionated about the provider in the following ways: - A root key will be created or referenced and never leaves the provider - the root key will be used to encrypt a "data key" - the data key is given to the client (us) for encrypting data - the client shall store only the encrypted data key - the client shall remove the plaintext data key from memory as soon as it is no longer needed - the client will request the data key be decrypted by the provider if it is needed subsequently. In this way the encryption-as-a-service provider scales to unlimited data sizes without needing to transfer the data to the remote service for symmetric encryption/decryption. To rotate root keys, generate new ones periodically and reencrypt data you touch with the new root. This can either be done all at once or gradually over time. Old root keys are out of circulation when no data exists that points to them.

type VaultConfig

type VaultConfig struct {
	TransitMount string // mounting point. defaults to /transit
	SecretMount  string // mounting point. defaults to /secret
	Token        string // vault token... should authenticate as machine to vault instead?
	Namespace    string
	Address      string
}

func NewVaultConfig

func NewVaultConfig() VaultConfig

type VaultSecretProvider

type VaultSecretProvider struct {
	VaultConfig
	// contains filtered or unexported fields
}

func NewVaultSecretProvider

func NewVaultSecretProvider(address, token, namespace string) (*VaultSecretProvider, error)

func NewVaultSecretProviderFromConfig

func NewVaultSecretProviderFromConfig(cfg VaultConfig) (*VaultSecretProvider, error)

func (*VaultSecretProvider) DecryptDataKey

func (v *VaultSecretProvider) DecryptDataKey(rootKeyID string, keyData []byte) (*SymmetricKey, error)

func (*VaultSecretProvider) GenerateDataKey

func (v *VaultSecretProvider) GenerateDataKey(rootKeyID string) (*SymmetricKey, error)

func (*VaultSecretProvider) GetSecret

func (v *VaultSecretProvider) GetSecret(name string) ([]byte, error)

func (*VaultSecretProvider) RemoteDecrypt

func (v *VaultSecretProvider) RemoteDecrypt(keyID string, encrypted []byte) (plain []byte, err error)

func (*VaultSecretProvider) RemoteEncrypt

func (v *VaultSecretProvider) RemoteEncrypt(keyID string, plain []byte) (encrypted []byte, err error)

func (*VaultSecretProvider) SetSecret

func (v *VaultSecretProvider) SetSecret(name string, secret []byte) error

Directories

Path Synopsis
testutil

Jump to

Keyboard shortcuts

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