Skip to content

Commit

Permalink
#328 Decrypt base64 encoded SOPS encrypted secrets #328
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bob.rohan committed Apr 21, 2021
1 parent 1ba5d2b commit e9b5e08
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions controllers/kustomization_decryptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controllers
import (
"bytes"
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -75,6 +76,61 @@ func (kd *KustomizeDecryptor) Decrypt(res *resource.Resource) (*resource.Resourc
return nil, err
}

if res.GetKind() == "Secret" {

dataMap := res.GetDataMap()

for key, value := range dataMap {

data, err := base64.StdEncoding.DecodeString(value)
if err != nil {
fmt.Println("Base64 Decode: %w", err)
}

if kd.kustomization.Spec.Decryption != nil && kd.kustomization.Spec.Decryption.Provider == DecryptionProviderSOPS &&
bytes.Contains(data, []byte("sops")) && bytes.Contains(data, []byte("ENC[")) {

store := common.StoreForFormat(formats.Yaml)

tree, err := store.LoadEncryptedFile(data)
if err != nil {
return nil, fmt.Errorf("LoadEncryptedFile: %w", err)
}

metadataKey, err := tree.Metadata.GetDataKeyWithKeyServices(
[]keyservice.KeyServiceClient{
intkeyservice.NewLocalClient(intkeyservice.NewServer(false, kd.homeDir, kd.ageIdentities)),
},
)

if err != nil {
if userErr, ok := err.(sops.UserError); ok {
err = fmt.Errorf(userErr.UserError())
}
return nil, fmt.Errorf("GetDataKey: %w", err)
}

cipher := aes.NewCipher()
if _, err := tree.Decrypt(metadataKey, cipher); err != nil {
return nil, fmt.Errorf("AES decrypt: %w", err)
}

binaryStore := common.StoreForFormat(formats.Binary)

out, err := binaryStore.EmitPlainFile(tree.Branches)
if err != nil {
return nil, fmt.Errorf("EmitPlainFile: %w", err)
}

dataMap[key] = base64.StdEncoding.EncodeToString(out)
}
}

res.SetDataMap(dataMap)

return res, nil
}

if kd.kustomization.Spec.Decryption != nil && kd.kustomization.Spec.Decryption.Provider == DecryptionProviderSOPS &&
bytes.Contains(out, []byte("sops:")) && bytes.Contains(out, []byte("mac: ENC[")) {
store := common.StoreForFormat(formats.Yaml)
Expand Down

0 comments on commit e9b5e08

Please sign in to comment.