2021-10-01 07:39:57 -05:00
|
|
|
package secrets
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-01-07 06:52:28 -06:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2022-05-23 06:13:55 -05:00
|
|
|
"time"
|
2021-10-01 07:39:57 -05:00
|
|
|
)
|
|
|
|
|
2021-11-04 11:47:21 -05:00
|
|
|
// Service is an envelope encryption service in charge of encrypting/decrypting secrets.
|
|
|
|
// It is a replacement for encryption.Service
|
2021-10-12 09:08:07 -05:00
|
|
|
type Service interface {
|
2021-11-16 04:51:13 -06:00
|
|
|
// Encrypt MUST NOT be used within database transactions, it may cause database locks.
|
|
|
|
// For those specific use cases where the encryption operation cannot be moved outside
|
|
|
|
// the database transaction, look at database-specific methods present at the specific
|
|
|
|
// implementation present at manager.SecretsService.
|
2021-10-12 09:08:07 -05:00
|
|
|
Encrypt(ctx context.Context, payload []byte, opt EncryptionOptions) ([]byte, error)
|
|
|
|
Decrypt(ctx context.Context, payload []byte) ([]byte, error)
|
2021-11-16 04:51:13 -06:00
|
|
|
|
|
|
|
// EncryptJsonData MUST NOT be used within database transactions.
|
|
|
|
// Look at Encrypt method comment for further details.
|
2021-10-12 09:08:07 -05:00
|
|
|
EncryptJsonData(ctx context.Context, kv map[string]string, opt EncryptionOptions) (map[string][]byte, error)
|
|
|
|
DecryptJsonData(ctx context.Context, sjd map[string][]byte) (map[string]string, error)
|
2021-11-16 04:51:13 -06:00
|
|
|
|
2021-10-12 09:08:07 -05:00
|
|
|
GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key, fallback string) string
|
2022-02-03 02:15:38 -06:00
|
|
|
|
2022-05-23 06:13:55 -05:00
|
|
|
RotateDataKeys(ctx context.Context) error
|
2022-02-03 02:15:38 -06:00
|
|
|
ReEncryptDataKeys(ctx context.Context) error
|
2021-10-01 07:39:57 -05:00
|
|
|
}
|
|
|
|
|
2021-11-04 11:47:21 -05:00
|
|
|
// Store defines methods to interact with secrets storage
|
2021-10-12 09:08:07 -05:00
|
|
|
type Store interface {
|
2022-05-23 06:13:55 -05:00
|
|
|
GetDataKey(ctx context.Context, id string) (*DataKey, error)
|
2022-06-04 05:55:49 -05:00
|
|
|
GetCurrentDataKey(ctx context.Context, label string) (*DataKey, error)
|
2021-10-12 09:08:07 -05:00
|
|
|
GetAllDataKeys(ctx context.Context) ([]*DataKey, error)
|
2022-05-23 06:13:55 -05:00
|
|
|
CreateDataKey(ctx context.Context, dataKey *DataKey) error
|
|
|
|
DisableDataKeys(ctx context.Context) error
|
|
|
|
DeleteDataKey(ctx context.Context, id string) error
|
2022-02-03 02:15:38 -06:00
|
|
|
ReEncryptDataKeys(ctx context.Context, providers map[ProviderID]Provider, currProvider ProviderID) error
|
2021-10-01 07:39:57 -05:00
|
|
|
}
|
|
|
|
|
2021-11-04 11:47:21 -05:00
|
|
|
// Provider is a key encryption key provider for envelope encryption
|
2021-10-01 07:39:57 -05:00
|
|
|
type Provider interface {
|
2021-10-07 09:33:50 -05:00
|
|
|
Encrypt(ctx context.Context, blob []byte) ([]byte, error)
|
|
|
|
Decrypt(ctx context.Context, blob []byte) ([]byte, error)
|
2021-10-01 07:39:57 -05:00
|
|
|
}
|
2022-01-07 06:52:28 -06:00
|
|
|
|
|
|
|
type ProviderID string
|
|
|
|
|
|
|
|
func (id ProviderID) Kind() (string, error) {
|
|
|
|
idStr := string(id)
|
|
|
|
|
|
|
|
parts := strings.SplitN(idStr, ".", 2)
|
|
|
|
if len(parts) != 2 {
|
|
|
|
return "", fmt.Errorf("malformatted provider identifier %s: expected format <provider>.<keyName>", idStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return parts[0], nil
|
|
|
|
}
|
2022-01-28 09:17:40 -06:00
|
|
|
|
2022-06-04 05:55:49 -05:00
|
|
|
func KeyLabel(scope string, providerID ProviderID) string {
|
2022-05-23 06:13:55 -05:00
|
|
|
return fmt.Sprintf("%s/%s@%s", time.Now().Format("2006-01-02"), scope, providerID)
|
|
|
|
}
|
|
|
|
|
2022-01-28 09:17:40 -06:00
|
|
|
// BackgroundProvider should be implemented for a provider that has a task that needs to be run in the background.
|
|
|
|
type BackgroundProvider interface {
|
|
|
|
Run(ctx context.Context) error
|
|
|
|
}
|
2022-07-04 05:17:21 -05:00
|
|
|
|
|
|
|
// Migrator is responsible for secrets migrations like re-encrypting or rolling back secrets.
|
|
|
|
type Migrator interface {
|
2022-07-18 01:57:58 -05:00
|
|
|
// ReEncryptSecrets decrypts and re-encrypts the secrets with most recent
|
|
|
|
// available data key. If a secret-specific decryption / re-encryption fails,
|
|
|
|
// it does not stop, but returns false as the first return (success or not)
|
|
|
|
// at the end of the process.
|
|
|
|
ReEncryptSecrets(ctx context.Context) (bool, error)
|
|
|
|
// RollBackSecrets decrypts and re-encrypts the secrets using the legacy
|
|
|
|
// encryption. If a secret-specific decryption / re-encryption fails, it
|
|
|
|
// does not stop, but returns false as the first return (success or not)
|
|
|
|
// at the end of the process.
|
|
|
|
RollBackSecrets(ctx context.Context) (bool, error)
|
2022-07-04 05:17:21 -05:00
|
|
|
}
|