Documentation
¶
Overview ¶
Package encryption is a generated GoMock package.
Index ¶
- Constants
- Variables
- func GenerateKey() ([]byte, error)
- func GetEncryptedDataVersion(data []byte) (int, error)
- func IsEncryptedData(data []byte) bool
- type EncryptedData
- type Encryptor
- func (e *Encryptor) Decrypt(data []byte, associatedData []byte) ([]byte, error)
- func (e *Encryptor) DecryptString(data string, associatedData []byte) (string, error)
- func (e *Encryptor) Encrypt(plaintext []byte, associatedData []byte) ([]byte, error)
- func (e *Encryptor) EncryptString(plaintext string, associatedData []byte) (string, error)
- type InMemoryKeyProvider
- func (p *InMemoryKeyProvider) AddKey(version int, key []byte) error
- func (p *InMemoryKeyProvider) GetCurrentKey(ctx context.Context) ([]byte, int, error)
- func (p *InMemoryKeyProvider) GetKeyByVersion(ctx context.Context, version int) ([]byte, error)
- func (p *InMemoryKeyProvider) SetCurrentVersion(version int) error
- type KeyData
- type KeyProvider
- type KeyStore
- type KubernetesKeyProvider
- type KubernetesKeyProviderOptions
- type MockKeyProvider
- type MockKeyProviderGetCurrentKeyCall
- func (c *MockKeyProviderGetCurrentKeyCall) Do(f func(context.Context) ([]byte, int, error)) *MockKeyProviderGetCurrentKeyCall
- func (c *MockKeyProviderGetCurrentKeyCall) DoAndReturn(f func(context.Context) ([]byte, int, error)) *MockKeyProviderGetCurrentKeyCall
- func (c *MockKeyProviderGetCurrentKeyCall) Return(arg0 []byte, arg1 int, arg2 error) *MockKeyProviderGetCurrentKeyCall
- type MockKeyProviderGetKeyByVersionCall
- func (c *MockKeyProviderGetKeyByVersionCall) Do(f func(context.Context, int) ([]byte, error)) *MockKeyProviderGetKeyByVersionCall
- func (c *MockKeyProviderGetKeyByVersionCall) DoAndReturn(f func(context.Context, int) ([]byte, error)) *MockKeyProviderGetKeyByVersionCall
- func (c *MockKeyProviderGetKeyByVersionCall) Return(arg0 []byte, arg1 error) *MockKeyProviderGetKeyByVersionCall
- type MockKeyProviderMockRecorder
- type SensitiveDataHandler
- func (h *SensitiveDataHandler) DecryptSensitiveFields(ctx context.Context, data map[string]any, sensitiveFieldPaths []string, ...) error
- func (h *SensitiveDataHandler) DecryptSensitiveFieldsWithSchema(ctx context.Context, data map[string]any, sensitiveFieldPaths []string, ...) error
- func (h *SensitiveDataHandler) EncryptSensitiveFields(data map[string]any, sensitiveFieldPaths []string, resourceID string) error
Constants ¶
const ( // KeySize is the required size for ChaCha20-Poly1305 keys (256 bits). KeySize = chacha20poly1305.KeySize // NonceSize is the size of the nonce for ChaCha20-Poly1305. NonceSize = chacha20poly1305.NonceSize )
const ( // This is the Secret's name, not actual credentials. DefaultEncryptionKeySecretName = "radius-encryption-key" //nolint:gosec // This is a Secret name, not credentials // DefaultEncryptionKeySecretKey is the key within the Secret that contains the versioned key store JSON. DefaultEncryptionKeySecretKey = "keys.json" // RadiusNamespace is the namespace where Radius secrets are stored. RadiusNamespace = "radius-system" )
Variables ¶
var ( // ErrInvalidKeySize is returned when the encryption key is not the correct size. ErrInvalidKeySize = errors.New("encryption key must be 32 bytes (256 bits)") // ErrEncryptionFailed is returned when encryption fails. ErrEncryptionFailed = errors.New("encryption failed") // ErrDecryptionFailed is returned when decryption fails. ErrDecryptionFailed = errors.New("decryption failed") // ErrInvalidEncryptedData is returned when the encrypted data format is invalid. ErrInvalidEncryptedData = errors.New("invalid encrypted data format") // ErrEmptyPlaintext is returned when attempting to encrypt empty data. ErrEmptyPlaintext = errors.New("plaintext cannot be empty") // ErrAssociatedDataMismatch is returned when the associated data provided during // decryption does not match what was used during encryption. ErrAssociatedDataMismatch = errors.New("associated data mismatch") )
var ( // ErrKeyNotFound is returned when the encryption key is not found. ErrKeyNotFound = errors.New("encryption key not found") // ErrKeyLoadFailed is returned when loading the encryption key fails. ErrKeyLoadFailed = errors.New("failed to load encryption key") // ErrKeyVersionNotFound is returned when a specific key version is not found. ErrKeyVersionNotFound = errors.New("key version not found") )
var ( // ErrFieldNotFound is returned when a field path cannot be found in the data. ErrFieldNotFound = errors.New("field not found") // ErrInvalidFieldPath is returned when a field path is invalid. ErrInvalidFieldPath = errors.New("invalid field path") // ErrFieldEncryptionFailed is returned when encryption of a field fails. ErrFieldEncryptionFailed = errors.New("field encryption failed") // ErrFieldDecryptionFailed is returned when decryption of a field fails. ErrFieldDecryptionFailed = errors.New("field decryption failed") )
Functions ¶
func GenerateKey ¶
GenerateKey generates a new random 256-bit encryption key.
func GetEncryptedDataVersion ¶
GetEncryptedDataVersion extracts the key version from encrypted data without decrypting. Returns 0 if the version is not present (for backwards compatibility with unversioned data).
func IsEncryptedData ¶
IsEncryptedData checks if the given data appears to be in the encrypted data format. It validates that the data is valid JSON with non-empty encrypted and nonce fields, and that both fields contain valid base64-encoded data with appropriate nonce size.
Types ¶
type EncryptedData ¶
type EncryptedData struct {
// Version is the key version used for encryption.
// This allows decryption to use the correct key when multiple versions exist.
Version int `json:"version,omitempty"`
// Encrypted contains the base64-encoded ciphertext.
Encrypted string `json:"encrypted"`
// Nonce contains the base64-encoded nonce used for encryption.
Nonce string `json:"nonce"`
// AD contains a hash of the associated data used during encryption (optional).
// This is stored for verification purposes - the actual AD must be provided during decryption.
// The hash allows detection of AD mismatches without exposing the AD value.
AD string `json:"ad,omitempty"`
}
EncryptedData represents the structure for storing encrypted data. It contains the base64-encoded ciphertext and nonce, plus optional associated data hash.
type Encryptor ¶
type Encryptor struct {
// contains filtered or unexported fields
}
Encryptor provides methods for encrypting and decrypting data using ChaCha20-Poly1305.
func NewEncryptor ¶
NewEncryptor creates a new Encryptor with the provided 256-bit key. Returns an error if the key is not exactly 32 bytes. The key version defaults to 0 (unversioned). Use NewEncryptorWithVersion for versioned keys.
func NewEncryptorWithVersion ¶
NewEncryptorWithVersion creates a new Encryptor with the provided key and version. The version is stored in encrypted data to enable decryption with the correct key.
func (*Encryptor) Decrypt ¶
Decrypt decrypts the data that was encrypted using the Encrypt method. The associatedData must match what was provided during encryption; if the AD was used during encryption, it must be provided here for successful decryption. The input should be JSON-encoded EncryptedData.
func (*Encryptor) DecryptString ¶
DecryptString decrypts the JSON-encoded encrypted data with associated data and returns the original string.
func (*Encryptor) Encrypt ¶
Encrypt encrypts the plaintext using ChaCha20-Poly1305 with Associated Data (AD). The AD provides authentication for contextual data (like resource ID or field path) without encrypting it. This binds the ciphertext to its context, preventing an attacker from moving encrypted values between different resources or fields.
The AD is authenticated but NOT encrypted - it must be provided again during decryption. A hash of the AD is stored in the encrypted data structure to allow early detection of mismatches.
Example AD values:
- Resource ID: "/planes/radius/local/resourceGroups/test/providers/Foo.Bar/myResources/test"
- Field path: "credentials.password"
- Combined: resourceID + ":" + fieldPath
Pass nil for associatedData if no context binding is needed (not recommended for sensitive data).
type InMemoryKeyProvider ¶
type InMemoryKeyProvider struct {
// contains filtered or unexported fields
}
InMemoryKeyProvider implements KeyProvider with in-memory versioned keys. This is useful for testing environments.
func NewInMemoryKeyProvider ¶
func NewInMemoryKeyProvider(key []byte) (*InMemoryKeyProvider, error)
NewInMemoryKeyProvider creates a new InMemoryKeyProvider with a single key at version 1.
func NewInMemoryKeyProviderWithVersions ¶
func NewInMemoryKeyProviderWithVersions(keys map[int][]byte, currentVersion int) (*InMemoryKeyProvider, error)
NewInMemoryKeyProviderWithVersions creates a new InMemoryKeyProvider with multiple versioned keys.
func (*InMemoryKeyProvider) AddKey ¶
func (p *InMemoryKeyProvider) AddKey(version int, key []byte) error
AddKey adds a new key version to the provider (useful for testing rotation).
func (*InMemoryKeyProvider) GetCurrentKey ¶
GetCurrentKey returns the current encryption key and its version.
func (*InMemoryKeyProvider) GetKeyByVersion ¶
GetKeyByVersion returns the key for a specific version.
func (*InMemoryKeyProvider) SetCurrentVersion ¶
func (p *InMemoryKeyProvider) SetCurrentVersion(version int) error
SetCurrentVersion sets the current version (useful for testing rotation).
type KeyData ¶
type KeyData struct {
// Key is the base64-encoded encryption key.
Key string `json:"key"`
// Version is the version number of this key.
Version int `json:"version"`
// CreatedAt is the timestamp when this key was created (RFC3339 format).
CreatedAt string `json:"createdAt"`
// ExpiresAt is the timestamp when this key expires (RFC3339 format).
ExpiresAt string `json:"expiresAt"`
}
KeyData represents a single encryption key with its metadata.
type KeyProvider ¶
type KeyProvider interface {
// GetCurrentKey retrieves the current (latest) encryption key for encrypting new data.
// Returns the key bytes, the version number, and any error.
// Returns ErrKeyNotFound if no key exists.
GetCurrentKey(ctx context.Context) (key []byte, version int, err error)
// GetKeyByVersion retrieves a specific key version for decryption.
// This is used when decrypting data that was encrypted with an older key.
// Returns ErrKeyVersionNotFound if the specified version does not exist.
GetKeyByVersion(ctx context.Context, version int) ([]byte, error)
}
KeyProvider defines the interface for retrieving encryption keys. It supports versioned keys to enable key rotation without data loss.
type KeyStore ¶
type KeyStore struct {
// CurrentVersion is the version number of the key to use for encryption.
CurrentVersion int `json:"currentVersion"`
// Keys is a map of version number (as string) to key data.
Keys map[string]KeyData `json:"keys"`
}
KeyStore represents a versioned key store containing multiple encryption keys. This structure matches the format used by the key rotation CronJob.
type KubernetesKeyProvider ¶
type KubernetesKeyProvider struct {
// contains filtered or unexported fields
}
KubernetesKeyProvider implements KeyProvider by loading the encryption key from a Kubernetes Secret.
func NewKubernetesKeyProvider ¶
func NewKubernetesKeyProvider(client controller_runtime.Client, opts *KubernetesKeyProviderOptions) *KubernetesKeyProvider
NewKubernetesKeyProvider creates a new KubernetesKeyProvider with the given Kubernetes client and options.
func (*KubernetesKeyProvider) GetCurrentKey ¶
GetCurrentKey retrieves the current encryption key from the Kubernetes Secret. Returns the key bytes, version number, and any error.
func (*KubernetesKeyProvider) GetKeyByVersion ¶
GetKeyByVersion retrieves a specific key version from the Kubernetes Secret.
type KubernetesKeyProviderOptions ¶
type KubernetesKeyProviderOptions struct {
// SecretName is the name of the Kubernetes Secret containing the encryption key.
// Defaults to DefaultEncryptionKeySecretName if not specified.
SecretName string
// SecretKey is the key within the Secret that contains the encryption key.
// Defaults to DefaultEncryptionKeySecretKey if not specified.
SecretKey string
// Namespace is the namespace where the Secret is located.
// Defaults to RadiusNamespace if not specified.
Namespace string
}
KubernetesKeyProviderOptions contains options for creating a KubernetesKeyProvider.
type MockKeyProvider ¶
type MockKeyProvider struct {
// contains filtered or unexported fields
}
MockKeyProvider is a mock of KeyProvider interface.
func NewMockKeyProvider ¶
func NewMockKeyProvider(ctrl *gomock.Controller) *MockKeyProvider
NewMockKeyProvider creates a new mock instance.
func (*MockKeyProvider) EXPECT ¶
func (m *MockKeyProvider) EXPECT() *MockKeyProviderMockRecorder
EXPECT returns an object that allows the caller to indicate expected use.
func (*MockKeyProvider) GetCurrentKey ¶
GetCurrentKey mocks base method.
func (*MockKeyProvider) GetKeyByVersion ¶
GetKeyByVersion mocks base method.
type MockKeyProviderGetCurrentKeyCall ¶
MockKeyProviderGetCurrentKeyCall wrap *gomock.Call
func (*MockKeyProviderGetCurrentKeyCall) Do ¶
func (c *MockKeyProviderGetCurrentKeyCall) Do(f func(context.Context) ([]byte, int, error)) *MockKeyProviderGetCurrentKeyCall
Do rewrite *gomock.Call.Do
func (*MockKeyProviderGetCurrentKeyCall) DoAndReturn ¶
func (c *MockKeyProviderGetCurrentKeyCall) DoAndReturn(f func(context.Context) ([]byte, int, error)) *MockKeyProviderGetCurrentKeyCall
DoAndReturn rewrite *gomock.Call.DoAndReturn
func (*MockKeyProviderGetCurrentKeyCall) Return ¶
func (c *MockKeyProviderGetCurrentKeyCall) Return(arg0 []byte, arg1 int, arg2 error) *MockKeyProviderGetCurrentKeyCall
Return rewrite *gomock.Call.Return
type MockKeyProviderGetKeyByVersionCall ¶
MockKeyProviderGetKeyByVersionCall wrap *gomock.Call
func (*MockKeyProviderGetKeyByVersionCall) Do ¶
func (c *MockKeyProviderGetKeyByVersionCall) Do(f func(context.Context, int) ([]byte, error)) *MockKeyProviderGetKeyByVersionCall
Do rewrite *gomock.Call.Do
func (*MockKeyProviderGetKeyByVersionCall) DoAndReturn ¶
func (c *MockKeyProviderGetKeyByVersionCall) DoAndReturn(f func(context.Context, int) ([]byte, error)) *MockKeyProviderGetKeyByVersionCall
DoAndReturn rewrite *gomock.Call.DoAndReturn
func (*MockKeyProviderGetKeyByVersionCall) Return ¶
func (c *MockKeyProviderGetKeyByVersionCall) Return(arg0 []byte, arg1 error) *MockKeyProviderGetKeyByVersionCall
Return rewrite *gomock.Call.Return
type MockKeyProviderMockRecorder ¶
type MockKeyProviderMockRecorder struct {
// contains filtered or unexported fields
}
MockKeyProviderMockRecorder is the mock recorder for MockKeyProvider.
func (*MockKeyProviderMockRecorder) GetCurrentKey ¶
func (mr *MockKeyProviderMockRecorder) GetCurrentKey(arg0 any) *MockKeyProviderGetCurrentKeyCall
GetCurrentKey indicates an expected call of GetCurrentKey.
func (*MockKeyProviderMockRecorder) GetKeyByVersion ¶
func (mr *MockKeyProviderMockRecorder) GetKeyByVersion(arg0, arg1 any) *MockKeyProviderGetKeyByVersionCall
GetKeyByVersion indicates an expected call of GetKeyByVersion.
type SensitiveDataHandler ¶
type SensitiveDataHandler struct {
// contains filtered or unexported fields
}
SensitiveDataHandler provides methods for encrypting and decrypting sensitive fields in data structures based on field paths marked with x-radius-sensitive annotation.
func NewSensitiveDataHandler ¶
func NewSensitiveDataHandler(encryptor *Encryptor) *SensitiveDataHandler
NewSensitiveDataHandler creates a new SensitiveDataHandler with the provided encryptor. Note: This constructor does not support versioned key rotation for decryption. Use NewSensitiveDataHandlerFromProvider for full versioned key support.
func NewSensitiveDataHandlerFromKey ¶
func NewSensitiveDataHandlerFromKey(key []byte) (*SensitiveDataHandler, error)
NewSensitiveDataHandlerFromKey creates a new SensitiveDataHandler from a raw encryption key. Note: This constructor does not support versioned key rotation for decryption. Use NewSensitiveDataHandlerFromProvider for full versioned key support.
func NewSensitiveDataHandlerFromProvider ¶
func NewSensitiveDataHandlerFromProvider(ctx context.Context, provider KeyProvider) (*SensitiveDataHandler, error)
NewSensitiveDataHandlerFromProvider creates a new SensitiveDataHandler using a versioned key provider. This is the recommended constructor as it supports key rotation: - Encryption uses the current key version - Decryption reads the version from encrypted data and fetches the appropriate key
func (*SensitiveDataHandler) DecryptSensitiveFields ¶
func (h *SensitiveDataHandler) DecryptSensitiveFields(ctx context.Context, data map[string]any, sensitiveFieldPaths []string, resourceID string) error
DecryptSensitiveFields decrypts all sensitive fields in the data based on the provided field paths. The data is modified in place. Field paths support dot notation and [*] for arrays/maps.
The resourceID must match what was provided during encryption for successful decryption. The context is used to fetch versioned keys from the key provider when needed.
Note: This method does not use schema information for type restoration. Numbers in decrypted objects will be returned as float64 (standard Go JSON behavior). For accurate type restoration, use DecryptSensitiveFieldsWithSchema instead.
Returns an error if any field decryption fails. In case of error, partial decryption may have occurred.
func (*SensitiveDataHandler) DecryptSensitiveFieldsWithSchema ¶
func (h *SensitiveDataHandler) DecryptSensitiveFieldsWithSchema(ctx context.Context, data map[string]any, sensitiveFieldPaths []string, resourceID string, schema map[string]any) error
DecryptSensitiveFieldsWithSchema decrypts all sensitive fields in the data using schema information for accurate type restoration. The schema should be the OpenAPI schema for the resource type. The data is modified in place. Field paths support dot notation and [*] for arrays/maps.
The resourceID must match what was provided during encryption for successful decryption. The context is used to fetch versioned keys from the key provider when needed. The schema is used to restore the correct types for fields within encrypted objects (e.g., integers that would otherwise be decoded as float64).
Returns an error if any field decryption fails. In case of error, partial decryption may have occurred.
func (*SensitiveDataHandler) EncryptSensitiveFields ¶
func (h *SensitiveDataHandler) EncryptSensitiveFields(data map[string]any, sensitiveFieldPaths []string, resourceID string) error
EncryptSensitiveFields encrypts all sensitive fields in the data based on the provided field paths. The data is modified in place. Field paths support dot notation and [*] for arrays/maps. Examples: "credentials.password", "secrets[*].value", "config[*]"
The resourceID is used as Associated Data (AD) for context binding. This prevents encrypted values from being moved between different resources. The resourceID should be the full resource ID (e.g., "/planes/radius/local/resourceGroups/test/providers/Foo.Bar/myResources/test").
Returns an error if any field encryption fails. In case of error, partial encryption may have occurred. Fields that are not found are skipped - this allows optional sensitive fields to be absent.