Secrets: Try to get the service identity from the context if not found in errors (#112598)

This commit is contained in:
Matheus Macabu
2025-10-17 17:35:01 +02:00
committed by GitHub
parent bbb5322008
commit 8512b219c5
2 changed files with 27 additions and 2 deletions
@@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/prometheus/client_golang/prometheus"
@@ -13,6 +14,7 @@ import (
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/metadata"
"github.com/grafana/authlib/authn"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana-app-sdk/logging"
@@ -66,6 +68,15 @@ func (s *decryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace,
start := time.Now()
// TEMPORARY: While we evaluate all of our auditing needs, provide one for decrypt operations.
defer func() {
// If at this point the identity is still empty, try to get it from the auth info in context.
if decrypterIdentity == "" {
if authInfo, ok := claims.AuthInfoFrom(ctx); authInfo != nil && ok {
if serviceIdentityList, ok := authInfo.GetExtra()[authn.ServiceIdentityKey]; ok && len(serviceIdentityList) > 0 {
decrypterIdentity = strings.TrimSpace(serviceIdentityList[0])
}
}
}
span.SetAttributes(attribute.String("decrypter.identity", decrypterIdentity))
args := []any{
@@ -43,13 +43,27 @@ func TestIntegrationDecrypt(t *testing.T) {
t.Cleanup(cancel)
// Create auth context with proper permissions
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues/group1:decrypt"}, "svc", types.TypeUser)
svcIdentity := "svc"
authCtx := createAuthContext(ctx, "default", []string{"secret.grafana.app/securevalues/group1:decrypt"}, svcIdentity, types.TypeUser)
fakeLogger := &mockLogger{}
loggerCtx := logging.Context(authCtx, fakeLogger)
sut := testutils.Setup(t)
exposed, err := sut.DecryptStorage.Decrypt(authCtx, "default", "non-existent-value")
exposed, err := sut.DecryptStorage.Decrypt(loggerCtx, "default", "non-existent-value")
require.Equal(t, err.Error(), contracts.ErrDecryptNotFound.Error()) // make sure we are stripping the error details
require.Empty(t, exposed)
require.Len(t, fakeLogger.InfoArgs, 2)
// we only want to check the audit log args
args := fakeLogger.InfoArgs[1]
require.Contains(t, args, "decrypter_identity")
for i, arg := range args {
if arg == "decrypter_identity" {
require.Equal(t, svcIdentity, args[i+1].(string))
}
}
})
t.Run("when happy path with valid auth and permissions, it returns decrypted value", func(t *testing.T) {