Secrets: Add more details about decryption when there is an error (#111741)
This commit is contained in:
@@ -26,5 +26,5 @@ type DecryptStorage interface {
|
||||
|
||||
// DecryptAuthorizer is the interface for authorizing decryption requests.
|
||||
type DecryptAuthorizer interface {
|
||||
Authorize(ctx context.Context, namespace xkube.Namespace, secureValueName string, secureValueDecrypters []string, owner []metav1.OwnerReference) (identity string, allowed bool)
|
||||
Authorize(ctx context.Context, namespace xkube.Namespace, secureValueName string, secureValueDecrypters []string, owner []metav1.OwnerReference) (identity string, allowed bool, reason string)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,13 @@ func ProvideDecryptAuthorizer(
|
||||
}
|
||||
|
||||
// Authorize checks whether the auth info token has the right permissions to decrypt the secure value.
|
||||
func (a *decryptAuthorizer) Authorize(ctx context.Context, ns xkube.Namespace, secureValueName string, secureValueDecrypters []string, owners []metav1.OwnerReference) (id string, isAllowed bool) {
|
||||
func (a *decryptAuthorizer) Authorize(
|
||||
ctx context.Context,
|
||||
ns xkube.Namespace,
|
||||
secureValueName string,
|
||||
secureValueDecrypters []string,
|
||||
owners []metav1.OwnerReference,
|
||||
) (id string, isAllowed bool, reason string) {
|
||||
ctx, span := a.tracer.Start(ctx, "DecryptAuthorizer.Authorize", trace.WithAttributes(
|
||||
attribute.String("name", secureValueName),
|
||||
attribute.StringSlice("decrypters", secureValueDecrypters),
|
||||
@@ -53,37 +59,37 @@ func (a *decryptAuthorizer) Authorize(ctx context.Context, ns xkube.Namespace, s
|
||||
|
||||
authInfo, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok {
|
||||
return "", false
|
||||
return "", false, "no auth info in context"
|
||||
}
|
||||
|
||||
if !claims.NamespaceMatches(authInfo.GetNamespace(), ns.String()) {
|
||||
return "", false
|
||||
return "", false, "namespace in token does not match the passed namespace"
|
||||
}
|
||||
|
||||
serviceIdentityList, ok := authInfo.GetExtra()[authn.ServiceIdentityKey]
|
||||
if !ok {
|
||||
return "", false
|
||||
return "", false, "no service identity in token"
|
||||
}
|
||||
|
||||
// If there's more than one service identity, something is suspicious and we reject it.
|
||||
if len(serviceIdentityList) != 1 {
|
||||
return "", false
|
||||
return "", false, "more than one service identity in token"
|
||||
}
|
||||
|
||||
serviceIdentity := strings.TrimSpace(serviceIdentityList[0])
|
||||
if len(serviceIdentity) == 0 {
|
||||
return "", false
|
||||
return "", false, "empty service identity in token"
|
||||
}
|
||||
|
||||
// Checks whether the token has the permission to decrypt secure values.
|
||||
if !hasPermissionInToken(authInfo.GetTokenPermissions(), secureValueName) {
|
||||
return serviceIdentity, false
|
||||
return serviceIdentity, false, "token does not have permission to decrypt secure values"
|
||||
}
|
||||
|
||||
// Check whether the service identity is allowed to decrypt this secure value.
|
||||
for _, decrypter := range secureValueDecrypters {
|
||||
if decrypter == serviceIdentity {
|
||||
return serviceIdentity, true
|
||||
return serviceIdentity, true, ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,14 +99,14 @@ func (a *decryptAuthorizer) Authorize(ctx context.Context, ns xkube.Namespace, s
|
||||
if extra.Identity == serviceIdentity {
|
||||
for _, owner := range owners {
|
||||
if strings.HasPrefix(owner.APIVersion, extra.Group) {
|
||||
return serviceIdentity, true
|
||||
return serviceIdentity, true, ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return serviceIdentity, false
|
||||
return serviceIdentity, false, "service identity is not in the secure value decrypters"
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/grafana/authlib/blob/1492b99410603ca15730a1805a9220ce48232bc3/authz/client.go#L138
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.Empty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -32,7 +32,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -41,7 +41,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "", []string{})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.Empty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -50,7 +50,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), " ", []string{})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.Empty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -60,13 +60,13 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
|
||||
// nameless
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
// named
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/name"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -76,13 +76,13 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
|
||||
// nameless
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:*"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
// named
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/name:something"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -91,7 +91,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -100,7 +100,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"wrong.group/securevalues/invalid:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -110,13 +110,13 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
|
||||
// nameless
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/invalid-resource:decrypt"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
// named
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/invalid-resource/name:decrypt"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", nil, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -125,7 +125,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.True(t, allowed)
|
||||
})
|
||||
@@ -135,13 +135,13 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
|
||||
// nameless
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"group2"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"group2"}, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
// named
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/name:decrypt"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", []string{"group2"}, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", []string{"group2"}, nil)
|
||||
require.NotEmpty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -151,13 +151,13 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
|
||||
// nameless
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.True(t, allowed)
|
||||
require.Equal(t, "identity", identity)
|
||||
|
||||
// named
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/name:decrypt"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "name", []string{"identity"}, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "name", []string{"identity"}, nil)
|
||||
require.True(t, allowed)
|
||||
require.Equal(t, "identity", identity)
|
||||
})
|
||||
@@ -172,11 +172,11 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "name1", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "name1", []string{"identity"}, nil)
|
||||
require.True(t, allowed)
|
||||
require.Equal(t, "identity", identity)
|
||||
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "name2", []string{"identity"}, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "name2", []string{"identity"}, nil)
|
||||
require.True(t, allowed)
|
||||
require.Equal(t, "identity", identity)
|
||||
})
|
||||
@@ -185,7 +185,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/name:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -194,7 +194,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues/:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -203,7 +203,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "name", []string{}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "name", []string{}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -212,7 +212,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity1", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity1", "identity2", "identity3"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity1", "identity2", "identity3"}, nil)
|
||||
require.Equal(t, "identity1", identity)
|
||||
require.True(t, allowed)
|
||||
})
|
||||
@@ -226,7 +226,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "test.grafana.app/v1",
|
||||
Kind: "Test",
|
||||
@@ -246,7 +246,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
_, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
_, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "test.grafana.app/v1",
|
||||
Kind: "Test",
|
||||
@@ -265,7 +265,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
_, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
_, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{}, []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "test.grafana.app/v1",
|
||||
Kind: "Test",
|
||||
@@ -278,17 +278,17 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
ctx := createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"SECRET.grafana.app/securevalues:decrypt"})
|
||||
identity, allowed := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/SECUREVALUES:decrypt"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
|
||||
ctx = createAuthContext(context.Background(), defaultNs.String(), "identity", []string{"secret.grafana.app/securevalues:DECRYPT"})
|
||||
identity, allowed = authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
identity, allowed, _ = authorizer.Authorize(ctx, defaultNs, "", []string{"identity"}, nil)
|
||||
require.Equal(t, "identity", identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
@@ -297,7 +297,7 @@ func TestDecryptAuthorizer(t *testing.T) {
|
||||
authorizer := ProvideDecryptAuthorizer(tracer, nil)
|
||||
|
||||
ctx := createAuthContext(context.Background(), "namespace1", "identity", []string{"secret.grafana.app/securevalues:decrypt"})
|
||||
identity, allowed := authorizer.Authorize(ctx, "namespace2", "", []string{"identity"}, nil)
|
||||
identity, allowed, _ := authorizer.Authorize(ctx, "namespace2", "", []string{"identity"}, nil)
|
||||
require.Empty(t, identity)
|
||||
require.False(t, allowed)
|
||||
})
|
||||
|
||||
@@ -14,6 +14,6 @@ type NoopAlwaysAllowedAuthorizer struct{}
|
||||
|
||||
var _ contracts.DecryptAuthorizer = &NoopAlwaysAllowedAuthorizer{}
|
||||
|
||||
func (a *NoopAlwaysAllowedAuthorizer) Authorize(context.Context, xkube.Namespace, string, []string, []metav1.OwnerReference) (string, bool) {
|
||||
return "", true
|
||||
func (a *NoopAlwaysAllowedAuthorizer) Authorize(context.Context, xkube.Namespace, string, []string, []metav1.OwnerReference) (string, bool, string) {
|
||||
return "", true, ""
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -83,22 +85,30 @@ func (s *decryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace,
|
||||
}
|
||||
}
|
||||
|
||||
decryptResultLabel := metrics.DecryptResultLabel(decryptErr)
|
||||
|
||||
if decryptErr == nil {
|
||||
span.SetStatus(codes.Ok, "Decrypt succeeded")
|
||||
args = append(args, "operation", "decrypt_secret_success")
|
||||
} else {
|
||||
span.SetStatus(codes.Error, "Decrypt failed")
|
||||
span.RecordError(decryptErr)
|
||||
args = append(args, "operation", "decrypt_secret_error", "error", decryptErr.Error(), "result", metrics.DecryptResultLabel(decryptErr))
|
||||
args = append(args, "operation", "decrypt_secret_error", "error", decryptErr.Error(), "result", decryptResultLabel)
|
||||
}
|
||||
|
||||
logging.FromContext(ctx).Info("Secrets Audit Log", args...)
|
||||
|
||||
s.metrics.DecryptDuration.WithLabelValues(metrics.DecryptResultLabel(decryptErr)).Observe(time.Since(start).Seconds())
|
||||
s.metrics.DecryptDuration.WithLabelValues(decryptResultLabel).Observe(time.Since(start).Seconds())
|
||||
|
||||
// Do not leak error details to caller, return only the wrapped domain errors.
|
||||
if decryptErr != nil {
|
||||
decryptErr = cmp.Or(errors.Unwrap(decryptErr), contracts.ErrDecryptFailed)
|
||||
}
|
||||
}()
|
||||
|
||||
// Basic authn check before reading a secure value metadata, it is here on purpose.
|
||||
if _, ok := claims.AuthInfoFrom(ctx); !ok {
|
||||
return "", contracts.ErrDecryptNotAuthorized
|
||||
return "", fmt.Errorf("no auth info in context (%w)", contracts.ErrDecryptNotAuthorized)
|
||||
}
|
||||
|
||||
// The auth token will not necessarily have the permission to read the secure value metadata,
|
||||
@@ -106,27 +116,27 @@ func (s *decryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace,
|
||||
// function call happens after this.
|
||||
sv, err := s.secureValueMetadataStorage.Read(ctx, namespace, name, contracts.ReadOpts{})
|
||||
if err != nil {
|
||||
return "", contracts.ErrDecryptNotFound
|
||||
return "", fmt.Errorf("failed to read secure value metadata storage: %v (%w)", err, contracts.ErrDecryptNotFound)
|
||||
}
|
||||
|
||||
decrypterIdentity, authorized := s.decryptAuthorizer.Authorize(ctx, namespace, name, sv.Spec.Decrypters, sv.OwnerReferences)
|
||||
decrypterIdentity, authorized, reason := s.decryptAuthorizer.Authorize(ctx, namespace, name, sv.Spec.Decrypters, sv.OwnerReferences)
|
||||
if !authorized {
|
||||
return "", contracts.ErrDecryptNotAuthorized
|
||||
return "", fmt.Errorf("failed to authorize decryption with reason %v (%w)", reason, contracts.ErrDecryptNotAuthorized)
|
||||
}
|
||||
|
||||
keeperConfig, err := s.keeperMetadataStorage.GetKeeperConfig(ctx, namespace.String(), sv.Spec.Keeper, contracts.ReadOpts{})
|
||||
if err != nil {
|
||||
return "", contracts.ErrDecryptFailed
|
||||
return "", fmt.Errorf("failed to read keeper config metadata storage: %v (%w)", err, contracts.ErrDecryptFailed)
|
||||
}
|
||||
|
||||
keeper, err := s.keeperService.KeeperForConfig(keeperConfig)
|
||||
if err != nil {
|
||||
return "", contracts.ErrDecryptFailed
|
||||
return "", fmt.Errorf("failed to get keeper for config: %v (%w)", err, contracts.ErrDecryptFailed)
|
||||
}
|
||||
|
||||
exposedValue, err := keeper.Expose(ctx, keeperConfig, namespace.String(), name, sv.Status.Version)
|
||||
if err != nil {
|
||||
return "", contracts.ErrDecryptFailed
|
||||
return "", fmt.Errorf("failed to expose secret: %v (%w)", err, contracts.ErrDecryptFailed)
|
||||
}
|
||||
|
||||
return exposedValue, nil
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
sut := testutils.Setup(t)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(ctx, "default", "name")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
sut := testutils.Setup(t)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", "non-existent-value")
|
||||
require.ErrorIs(t, err, contracts.ErrDecryptNotFound)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotFound.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", svName)
|
||||
require.ErrorIs(t, err, contracts.ErrDecryptNotAuthorized)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -146,7 +146,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", "sv-test")
|
||||
require.ErrorIs(t, err, contracts.ErrDecryptNotAuthorized)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -179,7 +179,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", svName)
|
||||
require.ErrorIs(t, err, contracts.ErrDecryptNotAuthorized)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details)
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -211,7 +211,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", "sv-test")
|
||||
require.ErrorIs(t, err, contracts.ErrDecryptNotAuthorized)
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
@@ -244,8 +244,7 @@ func TestIntegrationDecrypt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", svName)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err.Error(), "not authorized")
|
||||
require.Equal(t, err.Error(), contracts.ErrDecryptNotAuthorized.Error()) // make sure we are stripping the error details
|
||||
require.Empty(t, exposed)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user