-
Notifications
You must be signed in to change notification settings - Fork 15
/
vault_enckey.go
100 lines (86 loc) · 2.07 KB
/
vault_enckey.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package cmd
import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"time"
"github.com/cybozu-go/cke"
"github.com/cybozu-go/cke/op/k8s"
vault "github.com/hashicorp/vault/api"
"github.com/spf13/cobra"
)
var vaultEncKeyCmd = &cobra.Command{
Use: "enckey",
Short: "generate new encryption key for Kubernetes Secrets",
Long: `Generate or rotate encryption keys for Kubernetes Secrets.
WARNING: Key rotation is not fully implemented in this version!!
This command generates new encryption keys for Kubernetes Secrets and
rotate old keys. The current key, if any, is retained to decrypt
existing data. Other old keys are removed.`,
RunE: func(cmd *cobra.Command, args []string) error {
vc, err := inf.Vault()
if err != nil {
return err
}
err = rotateK8sEncryptionKey(vc)
if err != nil {
return err
}
fmt.Println("succeeded")
return nil
},
}
func init() {
vaultCmd.AddCommand(vaultEncKeyCmd)
}
func rotateK8sEncryptionKey(vc *vault.Client) error {
secret, err := vc.Logical().Read(cke.K8sSecret)
if err != nil {
return err
}
var enckeys map[string]interface{}
if secret != nil && secret.Data != nil {
enckeys = secret.Data
} else {
enckeys = make(map[string]interface{})
}
var cfg k8s.AESConfiguration
if data, ok := enckeys["aescbc"]; ok {
err = json.Unmarshal([]byte(data.(string)), &cfg)
if err != nil {
return err
}
}
newKey, err := generateKey()
if err != nil {
return err
}
keys := []k8s.Key{
{
Name: time.Now().UTC().Format(time.RFC3339),
Secret: base64.StdEncoding.EncodeToString(newKey),
},
}
if len(cfg.Keys) > 0 {
keys = append(keys, cfg.Keys[0])
}
cfg.Keys = keys
cfgData, err := json.Marshal(cfg)
if err != nil {
return err
}
enckeys["aescbc"] = string(cfgData)
_, err = vc.Logical().Write(cke.K8sSecret, enckeys)
return err
}
// generateKey generates key for aescbc
// ref: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers
func generateKey() ([]byte, error) {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
return nil, err
}
return key, nil
}