Skip to content

Commit 957d963

Browse files
committed
fix: get latest key version ID from DB for system rotate event
1 parent 5fbde21 commit 957d963

3 files changed

Lines changed: 55 additions & 29 deletions

File tree

internal/event-processor/reconciler_test.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -730,12 +730,19 @@ func TestVersionInfoPropagation(t *testing.T) {
730730

731731
testutils.CreateTestEntities(ctx, t, r, keyConfiguration, system, keyWithVersion, keyWithoutVersion)
732732

733-
// Setup plugin with version info for one key, not the other
734-
instance.pluginOp.HandleKeyRecord(keyWithVersionID, testplugins.EnabledKeyStatus)
735-
instance.pluginOp.SetKeyVersionInfo(keyWithVersionID, initialVersionID)
733+
// Create key versions in DB for keyWithVersion only
734+
kv := &model.KeyVersion{
735+
ExternalID: uuid.NewString(),
736+
KeyID: keyWithVersion.ID,
737+
Version: 1,
738+
NativeID: ptr.PointTo(initialVersionID),
739+
}
740+
err := r.Create(ctx, kv)
741+
require.NoError(t, err)
736742

743+
// Setup plugin handlers (required for TransformCryptoAccessData)
744+
instance.pluginOp.HandleKeyRecord(keyWithVersionID, testplugins.EnabledKeyStatus)
737745
instance.pluginOp.HandleKeyRecord(keyWithoutVerID, testplugins.EnabledKeyStatus)
738-
// No version info set for keyWithoutVersion
739746

740747
// Helper to resolve tasks and extract key access metadata
741748
resolveAndExtractKeyAccessData := func(jobType string, keyID string) map[string]any {
@@ -773,7 +780,7 @@ func TestVersionInfoPropagation(t *testing.T) {
773780
keyWithVersion.ID.String(),
774781
)
775782

776-
// Assert version info from GetKey is present
783+
// Assert version info from DB key version is present
777784
assert.Equal(t, keyWithVersionID, keyAccessData["keyID"])
778785
assert.Equal(t, initialVersionID, keyAccessData["versionIdentifier"])
779786
assert.Equal(t, testRoleArn, keyAccessData["roleArn"])
@@ -792,8 +799,15 @@ func TestVersionInfoPropagation(t *testing.T) {
792799
})
793800

794801
t.Run("should fetch fresh version info on every event creation", func(t *testing.T) {
795-
// Update version info in plugin (simulating rotation)
796-
instance.pluginOp.SetKeyVersionInfo(keyWithVersionID, updatedVersionID)
802+
// Simulate rotation by adding a newer key version in the DB
803+
kv := &model.KeyVersion{
804+
ExternalID: uuid.NewString(),
805+
KeyID: keyWithVersion.ID,
806+
Version: 2,
807+
NativeID: ptr.PointTo(updatedVersionID),
808+
}
809+
err := r.Create(ctx, kv)
810+
require.NoError(t, err)
797811

798812
keyAccessData := resolveAndExtractKeyAccessData(
799813
eventprocessor.JobTypeSystemSwitch.String(),

internal/event-processor/repo.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@ func updateSystem(ctx context.Context, r repo.Repo, system *model.System) error
7878
return nil
7979
}
8080

81+
func getNewestKeyVersionNativeID(ctx context.Context, r repo.Repo, keyID string) (string, error) {
82+
var kv model.KeyVersion
83+
84+
ck := repo.NewCompositeKey().Where(fmt.Sprintf("%s_%s", repo.KeyField, repo.IDField), keyID)
85+
query := repo.NewQuery().
86+
Where(repo.NewCompositeKeyGroup(ck)).
87+
Order(repo.OrderField{Field: repo.CreatedField, Direction: repo.Desc})
88+
89+
_, err := r.First(ctx, &kv, *query)
90+
if err != nil {
91+
return "", fmt.Errorf("failed to get newest key version for key %s: %w", keyID, err)
92+
}
93+
94+
if kv.NativeID == nil {
95+
return "", fmt.Errorf("newest key version for key %s has no native ID", keyID)
96+
}
97+
98+
return *kv.NativeID, nil
99+
}
100+
81101
func updateKey(ctx context.Context, r repo.Repo, key *model.Key) error {
82102
ck := repo.NewCompositeKey().Where(repo.IDField, key.ID)
83103
query := repo.NewQuery().Where(repo.NewCompositeKeyGroup(ck)).UpdateAll(true)

internal/event-processor/resolvers.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package eventprocessor
33
import (
44
"context"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"strings"
89

@@ -17,7 +18,6 @@ import (
1718
"github.com/openkcm/cmk/internal/log"
1819
"github.com/openkcm/cmk/internal/model"
1920
cmkpluginregistry "github.com/openkcm/cmk/internal/pluginregistry"
20-
"github.com/openkcm/cmk/internal/pluginregistry/service/api/common"
2121
"github.com/openkcm/cmk/internal/pluginregistry/service/api/keymanagement"
2222
"github.com/openkcm/cmk/internal/repo"
2323
cmkcontext "github.com/openkcm/cmk/utils/context"
@@ -193,33 +193,25 @@ func (r *SystemTaskInfoResolver) selectKeyForTask(
193193
return key, nil
194194
}
195195

196-
// fetchAndPopulateVersionInfo fetches current key version info from the keystore provider
197-
// and populates it into the crypto access data for all regions
196+
// fetchAndPopulateVersionInfo fetches the newest key version from the DB
197+
// and populates its native ID into the crypto access data for all regions.
198+
// If no key version exists, the crypto access data is returned unchanged for backward compatibility.
198199
func (r *SystemTaskInfoResolver) fetchAndPopulateVersionInfo(
199200
ctx context.Context,
200-
client keymanagement.KeyManagement,
201201
key model.Key,
202202
) (map[string]map[string]any, error) {
203-
// Fetch current version info from keystore provider
204-
configValues := key.GetManagementAccessData()
205-
freshKeyInfo, err := client.GetKey(ctx, &keymanagement.GetKeyRequest{
206-
Parameters: keymanagement.RequestParameters{
207-
Config: common.KeystoreConfig{Values: configValues},
208-
KeyID: *key.NativeID,
209-
},
210-
})
203+
cryptoData := key.GetCryptoAccessData()
204+
205+
latestVersionID, err := getNewestKeyVersionNativeID(ctx, r.repo, key.ID.String())
211206
if err != nil {
212-
return nil, fmt.Errorf("failed to get current key info: %w", err)
207+
if errors.Is(err, repo.ErrNotFound) {
208+
return cryptoData, nil
209+
}
210+
return nil, fmt.Errorf("failed to get latest key version native ID: %w", err)
213211
}
214212

215-
// Merge fresh version info into crypto access data
216-
cryptoData := key.GetCryptoAccessData()
217-
if freshKeyInfo.LatestKeyVersionId != "" {
218-
for region := range cryptoData {
219-
if freshKeyInfo.LatestKeyVersionId != "" {
220-
cryptoData[region]["versionIdentifier"] = freshKeyInfo.LatestKeyVersionId
221-
}
222-
}
213+
for region := range cryptoData {
214+
cryptoData[region]["versionIdentifier"] = latestVersionID
223215
}
224216

225217
return cryptoData, nil
@@ -241,7 +233,7 @@ func (r *SystemTaskInfoResolver) getKeyAccessMetadata(
241233
}
242234

243235
// Fetch and populate version info
244-
cryptoData, err := r.fetchAndPopulateVersionInfo(ctx, client, key)
236+
cryptoData, err := r.fetchAndPopulateVersionInfo(ctx, key)
245237
if err != nil {
246238
return nil, err
247239
}

0 commit comments

Comments
 (0)