Skip to content

Commit e9b5e08

Browse files
author
bob.rohan
committed
#328 Decrypt base64 encoded SOPS encrypted secrets #328
Kustomize-controller can currently decrypt SOPS encrypted files - but whole files only. Kubernetes Secrets are base64 encoded, therefore when a SOPS encrypted file, is added as base64 encoded data to a Kubernetes Secret, it is not decrypted.
1 parent 1ba5d2b commit e9b5e08

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

controllers/kustomization_decryptor.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package controllers
1919
import (
2020
"bytes"
2121
"context"
22+
"encoding/base64"
2223
"fmt"
2324
"io/ioutil"
2425
"os"
@@ -75,6 +76,61 @@ func (kd *KustomizeDecryptor) Decrypt(res *resource.Resource) (*resource.Resourc
7576
return nil, err
7677
}
7778

79+
if res.GetKind() == "Secret" {
80+
81+
dataMap := res.GetDataMap()
82+
83+
for key, value := range dataMap {
84+
85+
data, err := base64.StdEncoding.DecodeString(value)
86+
if err != nil {
87+
fmt.Println("Base64 Decode: %w", err)
88+
}
89+
90+
if kd.kustomization.Spec.Decryption != nil && kd.kustomization.Spec.Decryption.Provider == DecryptionProviderSOPS &&
91+
bytes.Contains(data, []byte("sops")) && bytes.Contains(data, []byte("ENC[")) {
92+
93+
store := common.StoreForFormat(formats.Yaml)
94+
95+
tree, err := store.LoadEncryptedFile(data)
96+
if err != nil {
97+
return nil, fmt.Errorf("LoadEncryptedFile: %w", err)
98+
}
99+
100+
metadataKey, err := tree.Metadata.GetDataKeyWithKeyServices(
101+
[]keyservice.KeyServiceClient{
102+
intkeyservice.NewLocalClient(intkeyservice.NewServer(false, kd.homeDir, kd.ageIdentities)),
103+
},
104+
)
105+
106+
if err != nil {
107+
if userErr, ok := err.(sops.UserError); ok {
108+
err = fmt.Errorf(userErr.UserError())
109+
}
110+
return nil, fmt.Errorf("GetDataKey: %w", err)
111+
}
112+
113+
cipher := aes.NewCipher()
114+
if _, err := tree.Decrypt(metadataKey, cipher); err != nil {
115+
return nil, fmt.Errorf("AES decrypt: %w", err)
116+
}
117+
118+
binaryStore := common.StoreForFormat(formats.Binary)
119+
120+
out, err := binaryStore.EmitPlainFile(tree.Branches)
121+
if err != nil {
122+
return nil, fmt.Errorf("EmitPlainFile: %w", err)
123+
}
124+
125+
dataMap[key] = base64.StdEncoding.EncodeToString(out)
126+
}
127+
}
128+
129+
res.SetDataMap(dataMap)
130+
131+
return res, nil
132+
}
133+
78134
if kd.kustomization.Spec.Decryption != nil && kd.kustomization.Spec.Decryption.Provider == DecryptionProviderSOPS &&
79135
bytes.Contains(out, []byte("sops:")) && bytes.Contains(out, []byte("mac: ENC[")) {
80136
store := common.StoreForFormat(formats.Yaml)

0 commit comments

Comments
 (0)