Skip to content

Commit

Permalink
keyring: warn if removing a key that was used for encrypting variables
Browse files Browse the repository at this point in the history
  • Loading branch information
pkazmierczak committed Dec 31, 2024
1 parent 06c8244 commit 8db579b
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
6 changes: 4 additions & 2 deletions api/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package api
import (
"fmt"
"net/url"
"strconv"
)

// Keyring is used to access the Variables keyring.
Expand Down Expand Up @@ -60,14 +61,15 @@ func (k *Keyring) List(q *QueryOptions) ([]*RootKeyMeta, *QueryMeta, error) {

// Delete deletes a specific inactive key from the keyring
func (k *Keyring) Delete(opts *KeyringDeleteOptions, w *WriteOptions) (*WriteMeta, error) {
wm, err := k.client.delete(fmt.Sprintf("/v1/operator/keyring/key/%v",
url.PathEscape(opts.KeyID)), nil, nil, w)
wm, err := k.client.delete(fmt.Sprintf("/v1/operator/keyring/key/%v?force=%v",
url.PathEscape(opts.KeyID), strconv.FormatBool(opts.Force)), nil, nil, w)
return wm, err
}

// KeyringDeleteOptions are parameters for the Delete API
type KeyringDeleteOptions struct {
KeyID string // UUID
Force bool
}

// Rotate requests a key rotation
Expand Down
4 changes: 3 additions & 1 deletion command/operator_root_keyring_remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ func (c *OperatorRootKeyringRemoveCommand) Name() string {
}

func (c *OperatorRootKeyringRemoveCommand) Run(args []string) int {
var verbose bool
var force, verbose bool

flags := c.Meta.FlagSet("root keyring remove", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&verbose, "verbose", false, "")
flags.BoolVar(&force, "force", false, "Forces deletion of the root keyring even if it's in use.")

if err := flags.Parse(args); err != nil {
return 1
Expand All @@ -76,6 +77,7 @@ func (c *OperatorRootKeyringRemoveCommand) Run(args []string) int {
}
_, err = client.Keyring().Delete(&api.KeyringDeleteOptions{
KeyID: removeKey,
Force: force,
}, nil)
if err != nil {
c.Ui.Error(fmt.Sprintf("error: %s", err))
Expand Down
9 changes: 9 additions & 0 deletions nomad/keyring_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,15 @@ func (k *Keyring) Delete(args *structs.KeyringDeleteRootKeyRequest, reply *struc
return fmt.Errorf("active root key cannot be deleted - call rotate first")
}

// make sure the key was used to encrypt an existing variable
rootKeyInUse, err := snap.IsRootKeyInUse(args.KeyID)
if err != nil {
return err
}
if rootKeyInUse && !args.Force {
return fmt.Errorf("root key in use, cannot delete")
}

_, index, err = k.srv.raftApply(structs.WrappedRootKeysDeleteRequestType, args)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions nomad/structs/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ type KeyringUpdateRootKeyMetaResponse struct {

type KeyringDeleteRootKeyRequest struct {
KeyID string
Force bool
WriteRequest
}

Expand Down

0 comments on commit 8db579b

Please sign in to comment.