mirror of
https://github.com/getsops/sops.git
synced 2026-02-05 12:45:21 +01:00
Merge pull request #1919 from daogilvie/allow-azure-keyvault-empty-version
feat(azkv): Skipping key-version will get latest key
This commit is contained in:
@@ -378,6 +378,11 @@ a key. This has the following form::
|
||||
|
||||
https://${VAULT_URL}/keys/${KEY_NAME}/${KEY_VERSION}
|
||||
|
||||
You can omit the version, and have just a trailing slash, and this will use
|
||||
whatever the latest version of the key is::
|
||||
|
||||
https://${VAULT_URL}/keys/${KEY_NAME}/
|
||||
|
||||
To create a Key Vault and assign your service principal permissions on it
|
||||
from the commandline:
|
||||
|
||||
@@ -401,6 +406,10 @@ Now you can encrypt a file using::
|
||||
|
||||
$ sops encrypt --azure-kv https://sops.vault.azure.net/keys/sops-key/some-string test.yaml > test.enc.yaml
|
||||
|
||||
or, without the version::
|
||||
|
||||
$ sops encrypt --azure-kv https://sops.vault.azure.net/keys/sops-key/ test.yaml > test.enc.yaml
|
||||
|
||||
And decrypt it using::
|
||||
|
||||
$ sops decrypt test.enc.yaml
|
||||
|
||||
@@ -79,12 +79,21 @@ func NewMasterKey(vaultURL string, keyName string, keyVersion string) *MasterKey
|
||||
// MasterKey. The URL format is {vaultUrl}/keys/{keyName}/{keyVersion}.
|
||||
func NewMasterKeyFromURL(url string) (*MasterKey, error) {
|
||||
url = strings.TrimSpace(url)
|
||||
re := regexp.MustCompile("^(https://[^/]+)/keys/([^/]+)/([^/]+)$")
|
||||
re := regexp.MustCompile("^(https://[^/]+)/keys/([^/]+)(/[^/]*)?$")
|
||||
parts := re.FindStringSubmatch(url)
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("could not parse %q into a valid Azure Key Vault MasterKey", url)
|
||||
return nil, fmt.Errorf("could not parse %q into a valid Azure Key Vault MasterKey %v", url, parts)
|
||||
}
|
||||
return NewMasterKey(parts[1], parts[2], parts[3]), nil
|
||||
// Blank key versions are supported in Azure Key Vault, as they default to the latest
|
||||
// version of the key. We need to put the actual version in the sops metadata block though
|
||||
var key *MasterKey
|
||||
if len(parts[3]) > 1 {
|
||||
key = NewMasterKey(parts[1], parts[2], parts[3][1:])
|
||||
} else {
|
||||
key = NewMasterKey(parts[1], parts[2], "")
|
||||
}
|
||||
err := key.ensureKeyHasVersion(context.Background())
|
||||
return key, err
|
||||
}
|
||||
|
||||
// MasterKeysFromURLs takes a comma separated list of Azure Key Vault URLs,
|
||||
@@ -145,6 +154,36 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
|
||||
return key.EncryptContext(context.Background(), dataKey)
|
||||
}
|
||||
|
||||
func (key *MasterKey) ensureKeyHasVersion(ctx context.Context) error {
|
||||
if (key.Version != "") {
|
||||
// Nothing to do
|
||||
return nil
|
||||
}
|
||||
|
||||
token, err := key.getTokenCredential()
|
||||
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
|
||||
return fmt.Errorf("failed to get Azure token credential to retrieve key version: %w", err)
|
||||
}
|
||||
|
||||
c, err := azkeys.NewClient(key.VaultURL, token, key.clientOptions)
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
|
||||
return fmt.Errorf("failed to construct Azure Key Vault client to retrieve key version: %w", err)
|
||||
}
|
||||
|
||||
kdetail, err := c.GetKey(ctx, key.Name, key.Version, nil)
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
|
||||
return fmt.Errorf("failed to fetch Azure Key to retrieve key version: %w", err)
|
||||
}
|
||||
key.Version = kdetail.Key.KID.Version()
|
||||
|
||||
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Version fetch succeeded")
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncryptContext takes a SOPS data key, encrypts it with Azure Key Vault, and stores
|
||||
// the result in the EncryptedKey field.
|
||||
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
|
||||
|
||||
Reference in New Issue
Block a user