Skip to content

Commit c088f51

Browse files
committed
Allow providing cluster-wide age identity via controller env var
Signed-off-by: Marcus Weiner <[email protected]>
1 parent 0fe3783 commit c088f51

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

internal/decryptor/decryptor.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
apierrors "k8s.io/apimachinery/pkg/api/errors"
4141
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
4242
"k8s.io/apimachinery/pkg/types"
43+
ctrl "sigs.k8s.io/controller-runtime"
4344
"sigs.k8s.io/controller-runtime/pkg/client"
4445
"sigs.k8s.io/kustomize/api/konfig"
4546
"sigs.k8s.io/kustomize/api/resource"
@@ -201,6 +202,15 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
201202
provider := d.kustomization.Spec.Decryption.Provider
202203
switch provider {
203204
case DecryptionProviderSOPS:
205+
// load age key from env variable
206+
globalAgeIdentities, err := age.GlobalIdentities()
207+
if err != nil {
208+
log := ctrl.LoggerFrom(ctx)
209+
log.Info("failed to decrypt age identity from environment, ignoring", "error", err)
210+
} else {
211+
d.ageIdentities = append(d.ageIdentities, globalAgeIdentities...)
212+
}
213+
204214
secretName := types.NamespacedName{
205215
Namespace: d.kustomization.GetNamespace(),
206216
Name: d.kustomization.Spec.Decryption.SecretRef.Name,
@@ -214,7 +224,6 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
214224
return fmt.Errorf("cannot get %s decryption Secret '%s': %w", provider, secretName, err)
215225
}
216226

217-
var err error
218227
for name, value := range secret.Data {
219228
switch filepath.Ext(name) {
220229
case DecryptionPGPExt:

internal/sops/age/keysource.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,32 @@ import (
1111
"bytes"
1212
"fmt"
1313
"io"
14+
"os"
1415
"strings"
1516

1617
"filippo.io/age"
1718
"filippo.io/age/armor"
1819
)
1920

21+
const (
22+
// SopsAgeKeyEnv can be set as an environment variable to provide
23+
// an additional key to use for decryption.
24+
SopsAgeKeyEnv = "FLUX_SOPS_AGE_KEY"
25+
)
26+
27+
// GlobalIdentities loads age identities from the [SopsAgeKeyEnv] environment variable.
28+
func GlobalIdentities() ([]age.Identity, error) {
29+
if globalKey, ok := os.LookupEnv(SopsAgeKeyEnv); ok {
30+
parsed, err := age.ParseIdentities(strings.NewReader(globalKey))
31+
if err != nil {
32+
return nil, fmt.Errorf("failed to parse age identities from env var: %w", err)
33+
}
34+
return parsed, nil
35+
}
36+
37+
return nil, nil
38+
}
39+
2040
// MasterKey is an age key used to Encrypt and Decrypt SOPS' data key.
2141
//
2242
// Adapted from https://github.com/mozilla/sops/blob/v3.7.2/age/keysource.go

0 commit comments

Comments
 (0)