open-vault/builtin/logical/transit/path_rotate.go
Alexander Scheel f9fdac0345
Transit UX improvements: show key policy, configs on write (#20652)
* Respond with cache size on config write

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Respond with key policy on write

This includes creating a key, but also trimming or rotating an
existing key.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add changelog entry

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Correctly handle locking around policy formatting

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Validate that responses are non-empty

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

---------

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2023-05-18 14:36:10 -04:00

96 lines
2.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package transit
import (
"context"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/keysutil"
"github.com/hashicorp/vault/sdk/logical"
)
func (b *backend) pathRotate() *framework.Path {
return &framework.Path{
Pattern: "keys/" + framework.GenericNameRegex("name") + "/rotate",
DisplayAttrs: &framework.DisplayAttributes{
OperationPrefix: operationPrefixTransit,
OperationVerb: "rotate",
OperationSuffix: "key",
},
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeString,
Description: "Name of the key",
},
"managed_key_name": {
Type: framework.TypeString,
Description: "The name of the managed key to use for the new version of this transit key",
},
"managed_key_id": {
Type: framework.TypeString,
Description: "The UUID of the managed key to use for the new version of this transit key",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.UpdateOperation: b.pathRotateWrite,
},
HelpSynopsis: pathRotateHelpSyn,
HelpDescription: pathRotateHelpDesc,
}
}
func (b *backend) pathRotateWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
managedKeyName := d.Get("managed_key_name").(string)
managedKeyId := d.Get("managed_key_id").(string)
// Get the policy
p, _, err := b.GetPolicy(ctx, keysutil.PolicyRequest{
Storage: req.Storage,
Name: name,
}, b.GetRandomReader())
if err != nil {
return nil, err
}
if p == nil {
return logical.ErrorResponse("key not found"), logical.ErrInvalidRequest
}
if !b.System().CachingDisabled() {
p.Lock(true)
}
defer p.Unlock()
if p.Type == keysutil.KeyType_MANAGED_KEY {
var keyId string
keyId, err = GetManagedKeyUUID(ctx, b, managedKeyName, managedKeyId)
if err != nil {
p.Unlock()
return nil, err
}
err = p.RotateManagedKey(ctx, req.Storage, keyId)
} else {
// Rotate the policy
err = p.Rotate(ctx, req.Storage, b.GetRandomReader())
}
if err != nil {
return nil, err
}
return b.formatKeyPolicy(p, nil)
}
const pathRotateHelpSyn = `Rotate named encryption key`
const pathRotateHelpDesc = `
This path is used to rotate the named key. After rotation,
new encryption requests using this name will use the new key,
but decryption will still be supported for older versions.
`