Browse Source

fix: decrypt remote secret for SecureString type (#3761)

Victor Santos 1 year ago
parent
commit
7343875bf7

+ 8 - 1
pkg/provider/aws/parameterstore/parameterstore.go

@@ -195,7 +195,8 @@ func (pm *ParameterStore) PushSecret(ctx context.Context, secret *corev1.Secret,
 	}
 
 	secretValue := ssm.GetParameterInput{
-		Name: &secretName,
+		Name:           &secretName,
+		WithDecryption: aws.Bool(true),
 	}
 
 	existing, err := pm.client.GetParameterWithContext(ctx, &secretValue)
@@ -219,6 +220,12 @@ func (pm *ParameterStore) PushSecret(ctx context.Context, secret *corev1.Secret,
 			return fmt.Errorf("secret not managed by external-secrets")
 		}
 
+		// When fetching a remote SecureString parameter without decrypting, the default value will always be 'sensitive'
+		// in this case, no updates will be pushed remotely
+		if existing.Parameter.Value != nil && *existing.Parameter.Value == "sensitive" {
+			return fmt.Errorf("unable to compare 'sensitive' result, ensure to request a decrypted value")
+		}
+
 		if existing.Parameter.Value != nil && *existing.Parameter.Value == string(value) {
 			return nil
 		}

+ 29 - 0
pkg/provider/aws/parameterstore/parameterstore_test.go

@@ -495,6 +495,34 @@ func TestPushSecret(t *testing.T) {
 				err: fmt.Errorf("failed to parse metadata: failed to parse JSON raw data: invalid character 'f' looking for beginning of object key string"),
 			},
 		},
+		"GetRemoteSecretWithoutDecryption": {
+			reason: "test if push secret's get remote source is encrypted for valid comparison",
+			args: args{
+				store: makeValidParameterStore().Spec.Provider.AWS,
+				metadata: &apiextensionsv1.JSON{
+					Raw: []byte(`
+					{
+						"parameterStoreType": "SecureString",
+						"parameterStoreKeyID": "arn:aws:kms:sa-east-1:00000000000:key/bb123123-b2b0-4f60-ac3a-44a13f0e6b6c"
+					}
+					`),
+				},
+				client: fakeps.Client{
+					PutParameterWithContextFn: fakeps.NewPutParameterWithContextFn(putParameterOutput, nil),
+					GetParameterWithContextFn: fakeps.NewGetParameterWithContextFn(&ssm.GetParameterOutput{
+						Parameter: &ssm.Parameter{
+							Type:  aws.String("SecureString"),
+							Value: aws.String("sensitive"),
+						},
+					}, nil),
+					DescribeParametersWithContextFn:  fakeps.NewDescribeParametersWithContextFn(describeParameterOutput, nil),
+					ListTagsForResourceWithContextFn: fakeps.NewListTagsForResourceWithContextFn(validListTagsForResourceOutput, nil),
+				},
+			},
+			want: want{
+				err: fmt.Errorf("unable to compare 'sensitive' result, ensure to request a decrypted value"),
+			},
+		},
 	}
 
 	for name, tc := range tests {
@@ -625,6 +653,7 @@ func TestGetSecret(t *testing.T) {
 		pstc.expectedSecret = "bang"
 		pstc.remoteRef.Property = "/shmoo"
 	}
+
 	// good case: extract property with `.`
 	setExtractPropertyWithDot := func(pstc *parameterstoreTestCase) {
 		pstc.apiOutput.Parameter.Value = aws.String(`{"/shmoo.boom": "bang"}`)