Secrets: Remove temporary allowlist (#108118)

This commit is contained in:
Matheus Macabu
2025-07-16 09:39:33 +02:00
committed by GitHub
parent 56543db16a
commit 3cda233468
10 changed files with 76 additions and 221 deletions
@@ -23,6 +23,3 @@ type DecryptStorage interface {
type DecryptAuthorizer interface {
Authorize(ctx context.Context, secureValueName string, secureValueDecrypters []string) (identity string, allowed bool)
}
// TEMPORARY: Needed to pass it with wire.
type DecryptAllowList map[string]struct{}
@@ -1,8 +0,0 @@
package decrypt
import "github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
// TEMPORARY
func ProvideDecryptAllowList() contracts.DecryptAllowList {
return make(map[string]struct{}, 0)
}
+6 -14
View File
@@ -15,14 +15,12 @@ import (
// decryptAuthorizer is the authorizer implementation for decrypt operations.
type decryptAuthorizer struct {
tracer trace.Tracer
allowList contracts.DecryptAllowList
tracer trace.Tracer
}
func ProvideDecryptAuthorizer(tracer trace.Tracer, allowList contracts.DecryptAllowList) contracts.DecryptAuthorizer {
func ProvideDecryptAuthorizer(tracer trace.Tracer) contracts.DecryptAuthorizer {
return &decryptAuthorizer{
tracer: tracer,
allowList: allowList,
tracer: tracer,
}
}
@@ -56,15 +54,9 @@ func (a *decryptAuthorizer) Authorize(ctx context.Context, secureValueName strin
return "", false
}
serviceIdentity := serviceIdentityList[0]
// TEMPORARY: while we can't onboard every app into secrets, we can block them from decrypting
// securevalues preemptively here before even reaching out to the database.
// This check can be removed once we open the gates for any service to use secrets.
if len(a.allowList) > 0 {
if _, exists := a.allowList[serviceIdentity]; !exists || serviceIdentity == "" {
return serviceIdentity, false
}
serviceIdentity := strings.TrimSpace(serviceIdentityList[0])
if len(serviceIdentity) == 0 {
return "", false
}
// Checks whether the token has the permission to decrypt secure values.
@@ -17,7 +17,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when no auth info is present, it returns false", func(t *testing.T) {
ctx := context.Background()
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.Empty(t, identity)
@@ -26,7 +26,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when token permissions are empty, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{})
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.NotEmpty(t, identity)
@@ -35,7 +35,16 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when service identity is empty, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "", []string{})
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.Empty(t, identity)
require.False(t, allowed)
})
t.Run("when service identity is empty string, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), " ", []string{})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.Empty(t, identity)
@@ -43,7 +52,7 @@ func TestDecryptAuthorizer(t *testing.T) {
})
t.Run("when permission format is malformed (missing verb), it returns false", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
// nameless
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues"})
@@ -59,7 +68,7 @@ func TestDecryptAuthorizer(t *testing.T) {
})
t.Run("when permission verb is not exactly `decrypt`, it returns false", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
// nameless
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:*"})
@@ -76,7 +85,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when permission does not have 2 or 3 parts, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.NotEmpty(t, identity)
@@ -85,7 +94,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when permission has group that is not `secret.grafana.app`, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"wrong.group/securevalues/invalid:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.NotEmpty(t, identity)
@@ -93,7 +102,7 @@ func TestDecryptAuthorizer(t *testing.T) {
})
t.Run("when permission has resource that is not `securevalues`, it returns false", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
// nameless
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/invalid-resource:decrypt"})
@@ -110,24 +119,15 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when the allow list is empty, it allows all identities", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, nil)
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", []string{"identity"})
require.NotEmpty(t, identity)
require.True(t, allowed)
})
t.Run("when the identity is not in the allow list, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"allowed1": {}})
identity, allowed := authorizer.Authorize(ctx, "", nil)
require.NotEmpty(t, identity)
require.False(t, allowed)
})
t.Run("when the identity doesn't match any allowed decrypters, it returns false", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
// nameless
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
@@ -143,7 +143,7 @@ func TestDecryptAuthorizer(t *testing.T) {
})
t.Run("when the identity matches an allowed decrypter, it returns true", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
// nameless
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
@@ -166,7 +166,7 @@ func TestDecryptAuthorizer(t *testing.T) {
"wrong.group/securevalues/group2:decrypt",
"secret.grafana.app/securevalues/identity:decrypt", // old style of identity+permission
})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "name1", []string{"identity"})
require.True(t, allowed)
@@ -179,7 +179,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when empty secure value name with specific permission, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues/name:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", []string{"identity"})
require.Equal(t, "identity", identity)
@@ -188,7 +188,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when permission has an extra / but no name, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues/:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", []string{"identity"})
require.Equal(t, "identity", identity)
@@ -197,7 +197,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when the decrypters list is empty, meaning nothing can decrypt the secure value, it returns false", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "name", []string{})
require.Equal(t, "identity", identity)
@@ -206,7 +206,7 @@ func TestDecryptAuthorizer(t *testing.T) {
t.Run("when one of decrypters matches the identity, it returns true", func(t *testing.T) {
ctx := createAuthContext(context.Background(), "identity1", []string{"secret.grafana.app/securevalues:decrypt"})
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity1": {}, "identity2": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
identity, allowed := authorizer.Authorize(ctx, "", []string{"identity1", "identity2", "identity3"})
require.Equal(t, "identity1", identity)
@@ -214,7 +214,7 @@ func TestDecryptAuthorizer(t *testing.T) {
})
t.Run("permissions must be case-sensitive and return false", func(t *testing.T) {
authorizer := ProvideDecryptAuthorizer(tracer, map[string]struct{}{"identity": {}})
authorizer := ProvideDecryptAuthorizer(tracer)
ctx := createAuthContext(context.Background(), "identity", []string{"SECRET.grafana.app/securevalues:decrypt"})
identity, allowed := authorizer.Authorize(ctx, "", []string{"identity"})
@@ -6,13 +6,13 @@ import (
"github.com/grafana/authlib/authn"
"github.com/grafana/authlib/types"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
encryptionstorage "github.com/grafana/grafana/pkg/storage/secret/encryption"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/trace/noop"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/decrypt"
@@ -28,14 +28,13 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/secret/database"
encryptionstorage "github.com/grafana/grafana/pkg/storage/secret/encryption"
"github.com/grafana/grafana/pkg/storage/secret/metadata"
"github.com/grafana/grafana/pkg/storage/secret/migrator"
"github.com/stretchr/testify/require"
)
type SetupConfig struct {
KeeperService contracts.KeeperService
AllowList map[string]struct{}
}
func defaultSetupCfg() SetupConfig {
@@ -121,7 +120,7 @@ func Setup(t *testing.T, opts ...func(*SetupConfig)) Sut {
secureValueService := service.ProvideSecureValueService(tracer, accessClient, database, secureValueMetadataStorage, keeperMetadataStorage, keeperService)
decryptAuthorizer := decrypt.ProvideDecryptAuthorizer(tracer, setupCfg.AllowList)
decryptAuthorizer := decrypt.ProvideDecryptAuthorizer(tracer)
decryptStorage, err := metadata.ProvideDecryptStorage(features, tracer, keeperService, keeperMetadataStorage, secureValueMetadataStorage, decryptAuthorizer, nil)
require.NoError(t, err)
@@ -2,7 +2,6 @@ package validator
import (
"errors"
"fmt"
"strconv"
"strings"
@@ -14,16 +13,12 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
type secureValueValidator struct {
decryptersAllowList contracts.DecryptAllowList
}
type secureValueValidator struct{}
var _ contracts.SecureValueValidator = &secureValueValidator{}
func ProvideSecureValueValidator(decryptersAllowList contracts.DecryptAllowList) contracts.SecureValueValidator {
return &secureValueValidator{
decryptersAllowList: decryptersAllowList,
}
func ProvideSecureValueValidator() contracts.SecureValueValidator {
return &secureValueValidator{}
}
func (v *secureValueValidator) Validate(sv, oldSv *secretv1beta1.SecureValue, operation admission.Operation) field.ErrorList {
@@ -50,7 +45,7 @@ func (v *secureValueValidator) Validate(sv, oldSv *secretv1beta1.SecureValue, op
)
}
if errs := validateDecrypters(sv.Spec.Decrypters, v.decryptersAllowList); len(errs) > 0 {
if errs := validateDecrypters(sv.Spec.Decrypters); len(errs) > 0 {
return errs
}
@@ -107,7 +102,7 @@ func validateSecureValueUpdate(sv, oldSv *secretv1beta1.SecureValue) field.Error
}
// validateDecrypters validates that (if populated) the `decrypters` must be unique.
func validateDecrypters(decrypters []string, decryptersAllowList map[string]struct{}) field.ErrorList {
func validateDecrypters(decrypters []string) field.ErrorList {
errs := make(field.ErrorList, 0)
// Limit the number of decrypters to 64 to not have it unbounded.
@@ -134,20 +129,6 @@ func validateDecrypters(decrypters []string, decryptersAllowList map[string]stru
continue
}
// Allow List: decrypters must match exactly and be in the allowed list to be able to decrypt.
if len(decryptersAllowList) > 0 {
if _, exists := decryptersAllowList[decrypter]; !exists {
errs = append(
errs,
field.Invalid(field.NewPath("spec", "decrypters", "["+strconv.Itoa(i)+"]"), decrypter, fmt.Sprintf("allowed values: %v", decryptersAllowList)),
)
return errs
}
continue
}
// Use the same validation as labels for the decrypters.
if verrs := validation.IsValidLabelValue(decrypter); len(verrs) > 0 {
for _, verr := range verrs {
@@ -2,8 +2,6 @@ package validator
import (
"fmt"
"maps"
"slices"
"strings"
"testing"
@@ -31,7 +29,7 @@ func TestValidateSecureValue(t *testing.T) {
sv := validSecureValue.DeepCopy()
sv.Spec.Description = ""
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec.description", errs[0].Field)
@@ -43,7 +41,7 @@ func TestValidateSecureValue(t *testing.T) {
sv.Spec.Value = nil
sv.Spec.Ref = nil
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -52,7 +50,7 @@ func TestValidateSecureValue(t *testing.T) {
sv.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue(""))
sv.Spec.Ref = nil
validator = ProvideSecureValueValidator(nil)
validator = ProvideSecureValueValidator()
errs = validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -62,7 +60,7 @@ func TestValidateSecureValue(t *testing.T) {
sv.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("value"))
sv.Spec.Ref = &ref
validator = ProvideSecureValueValidator(nil)
validator = ProvideSecureValueValidator()
errs = validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -73,7 +71,7 @@ func TestValidateSecureValue(t *testing.T) {
sv.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue(strings.Repeat("a", contracts.SECURE_VALUE_RAW_INPUT_MAX_SIZE_BYTES+1)))
sv.Spec.Ref = nil
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec.value", errs[0].Field)
@@ -95,7 +93,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -115,7 +113,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -137,7 +135,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -148,7 +146,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator = ProvideSecureValueValidator(nil)
validator = ProvideSecureValueValidator()
errs = validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -167,7 +165,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, oldSv, admission.Update)
require.Empty(t, errs)
})
@@ -175,7 +173,7 @@ func TestValidateSecureValue(t *testing.T) {
t.Run("when the old object is `nil` it returns an error", func(t *testing.T) {
sv := &secretv1beta1.SecureValue{}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -196,7 +194,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
@@ -216,75 +214,25 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec.decrypters.[1]", errs[0].Field)
})
t.Run("when set, the `decrypters` must be one of the allowed in the allow list", func(t *testing.T) {
allowList := map[string]struct{}{"app1": {}, "app2": {}}
decrypters := slices.Collect(maps.Keys(allowList))
t.Run("`decrypters` list can be empty", func(t *testing.T) {
ref := "ref"
sv := &secretv1beta1.SecureValue{
Spec: secretv1beta1.SecureValueSpec{
Description: "description", Ref: &ref,
t.Run("no matches, returns an error", func(t *testing.T) {
ref := "ref"
sv := &secretv1beta1.SecureValue{
Spec: secretv1beta1.SecureValueSpec{
Description: "description", Ref: &ref,
Decrypters: []string{},
},
}
Decrypters: []string{"app3"},
},
}
validator := ProvideSecureValueValidator(allowList)
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
})
t.Run("no decrypters, returns no error", func(t *testing.T) {
ref := "ref"
sv := &secretv1beta1.SecureValue{
Spec: secretv1beta1.SecureValueSpec{
Description: "description", Ref: &ref,
Decrypters: []string{},
},
}
validator := ProvideSecureValueValidator(allowList)
errs := validator.Validate(sv, nil, admission.Create)
require.Empty(t, errs)
})
t.Run("one match, returns no errors", func(t *testing.T) {
ref := "ref"
sv := &secretv1beta1.SecureValue{
Spec: secretv1beta1.SecureValueSpec{
Description: "description", Ref: &ref,
Decrypters: []string{decrypters[0]},
},
}
validator := ProvideSecureValueValidator(allowList)
errs := validator.Validate(sv, nil, admission.Create)
require.Empty(t, errs)
})
t.Run("all matches, returns no errors", func(t *testing.T) {
ref := "ref"
sv := &secretv1beta1.SecureValue{
Spec: secretv1beta1.SecureValueSpec{
Description: "description", Ref: &ref,
Decrypters: decrypters,
},
}
validator := ProvideSecureValueValidator(allowList)
errs := validator.Validate(sv, nil, admission.Create)
require.Empty(t, errs)
})
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Empty(t, errs)
})
t.Run("`decrypters` must be a valid label value", func(t *testing.T) {
@@ -310,7 +258,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 3)
})
@@ -330,7 +278,7 @@ func TestValidateSecureValue(t *testing.T) {
},
}
validator := ProvideSecureValueValidator(nil)
validator := ProvideSecureValueValidator()
errs := validator.Validate(sv, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec.decrypters", errs[0].Field)
-2
View File
@@ -13,7 +13,6 @@ import (
"go.opentelemetry.io/otel/trace"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/api"
"github.com/grafana/grafana/pkg/api/avatar"
"github.com/grafana/grafana/pkg/api/routing"
@@ -426,7 +425,6 @@ var wireBasicSet = wire.NewSet(
secretmetadata.ProvideKeeperMetadataStorage,
secretmetadata.ProvideDecryptStorage,
secretdecrypt.ProvideDecryptAuthorizer,
secretdecrypt.ProvideDecryptAllowList,
secretdecrypt.ProvideDecryptService,
secretencryption.ProvideDataKeyStorage,
secretencryption.ProvideEncryptedValueStorage,
File diff suppressed because one or more lines are too long
@@ -44,53 +44,13 @@ func TestIntegrationDecrypt(t *testing.T) {
// Create auth context with proper permissions
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues/group1:decrypt"}, "svc", types.TypeUser)
sut := testutils.Setup(t, testutils.WithMutateCfg(func(sc *testutils.SetupConfig) {
sc.AllowList = map[string]struct{}{"group1": {}}
}))
sut := testutils.Setup(t)
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", "non-existent-value")
require.ErrorIs(t, err, contracts.ErrDecryptNotFound)
require.Empty(t, exposed)
})
t.Run("when auth info is not in allowlist, it returns an unauthorized error", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
svName := "sv-test"
svcIdentity := "svc"
// Create auth context with identity that is not in allowlist
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues/" + svName + ":decrypt"}, svcIdentity, types.TypeUser)
// Create an allowlist that doesn't include the permission
allowList := map[string]struct{}{"allowed-group": {}}
// Setup service
sut := testutils.Setup(t, testutils.WithMutateCfg(func(sc *testutils.SetupConfig) {
sc.AllowList = allowList
}))
// Create a secure value that is not in the allowlist
spec := secretv1beta1.SecureValueSpec{
Description: "description",
Decrypters: []string{svcIdentity},
Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")),
}
sv := &secretv1beta1.SecureValue{Spec: spec}
sv.Name = svName
sv.Namespace = "default"
_, err := sut.CreateSv(authCtx, testutils.CreateSvWithSv(sv))
require.NoError(t, err)
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", svName)
require.ErrorIs(t, err, contracts.ErrDecryptNotAuthorized)
require.Empty(t, exposed)
})
t.Run("when happy path with valid auth and permissions, it returns decrypted value", func(t *testing.T) {
t.Parallel()
@@ -102,15 +62,10 @@ func TestIntegrationDecrypt(t *testing.T) {
// Create auth context with proper permissions that match the decrypters
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues:decrypt"}, svcIdentity, types.TypeUser)
// Include the group in allowlist
allowList := map[string]struct{}{svcIdentity: {}}
// Setup service
sut := testutils.Setup(t, testutils.WithMutateCfg(func(sc *testutils.SetupConfig) {
sc.AllowList = allowList
}))
sut := testutils.Setup(t)
// Create a secure value that is in the allowlist
// Create a secure value
spec := secretv1beta1.SecureValueSpec{
Description: "description",
Decrypters: []string{svcIdentity},
@@ -141,15 +96,10 @@ func TestIntegrationDecrypt(t *testing.T) {
// Create auth context with proper permissions that match the decrypters
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues/sv-test2:decrypt"}, svcIdentity, types.TypeUser)
// Include the group in allowlist
allowList := map[string]struct{}{svcIdentity: {}}
// Setup service
sut := testutils.Setup(t, testutils.WithMutateCfg(func(sc *testutils.SetupConfig) {
sc.AllowList = allowList
}))
sut := testutils.Setup(t)
// Create a secure value that is in the allowlist
// Create a secure value
spec := secretv1beta1.SecureValueSpec{
Description: "description",
Decrypters: []string{svcIdentity},