@@ -227,19 +227,17 @@ func getMachineConfig(ctx context.Context, helper *helper.Helper) (mc.MachineCon
227227 return masterMachineConfig , nil
228228}
229229
230- // RegistryMapping pairs a mirror registry with its upstream source from IDMS/ICSP .
230+ // RegistryMapping pairs a mirror with its upstream source.
231231type RegistryMapping struct {
232- Mirror string `json:"mirror"`
233- Source string `json:"source"`
232+ Mirror string `json:"mirror"`
233+ Source string `json:"source"`
234+ SignedPrefix string `json:"signedPrefix,omitempty"`
234235}
235236
236- // SigstorePolicyInfo contains the EDPM-relevant parts of a ClusterImagePolicy.
237- // A single RemapIdentity signedPrefix covers all mirrors under the same registry
238- // root — the container runtime replaces only the prefix, preserving namespace paths.
237+ // SigstorePolicyInfo contains the EDPM sigstore settings.
239238type SigstorePolicyInfo struct {
240239 RegistryMappings []RegistryMapping
241240 CosignKeyData string
242- SignedPrefix string
243241}
244242
245243const (
@@ -319,6 +317,24 @@ func listClusterImagePolicies(
319317 return policyList , nil
320318}
321319
320+ func collectMatchedMirrorScopes (policyScopes []string , mirrorScopes []string ) []string {
321+ matchedMirrorScopes := map [string ]struct {}{}
322+ for _ , scope := range policyScopes {
323+ policyScope := normalizeImageScope (scope )
324+ if policyScope == "" {
325+ continue
326+ }
327+
328+ for _ , mirrorScope := range mirrorScopes {
329+ if clusterImagePolicyScopeMatchesMirror (policyScope , mirrorScope ) {
330+ matchedMirrorScopes [mirrorScope ] = struct {}{}
331+ }
332+ }
333+ }
334+
335+ return sortedSetKeys (matchedMirrorScopes )
336+ }
337+
322338// GetSigstoreImagePolicy checks if OCP has a ClusterImagePolicy configured
323339// with sigstore signature verification for one of the mirror registries in use.
324340// sourceByMirror maps each mirror scope to its upstream source registry (from IDMS/ICSP).
@@ -345,8 +361,25 @@ func GetSigstoreImagePolicy(ctx context.Context, helper *helper.Helper, mirrorSc
345361 return nil , nil
346362 }
347363
348- var matches []string
349- var match * SigstorePolicyInfo
364+ type policyMatch struct {
365+ name string
366+ keyData string
367+ signedPrefix string
368+ }
369+
370+ normalizedMirrors := make ([]string , 0 , len (mirrorScopes ))
371+ sourceByNormalizedMirror := make (map [string ]string , len (sourceByMirror ))
372+ for _ , mirrorScope := range mirrorScopes {
373+ normalizedMirror := normalizeImageScope (mirrorScope )
374+ if normalizedMirror == "" {
375+ continue
376+ }
377+ normalizedMirrors = append (normalizedMirrors , normalizedMirror )
378+ sourceByNormalizedMirror [normalizedMirror ] = sourceByMirror [mirrorScope ]
379+ }
380+ sort .Strings (normalizedMirrors )
381+
382+ matchByMirror := map [string ]policyMatch {}
350383
351384 for _ , policy := range policyList .Items {
352385 if policy .GetName () == "openshift" {
@@ -392,47 +425,57 @@ func GetSigstoreImagePolicy(ctx context.Context, helper *helper.Helper, mirrorSc
392425 }
393426 }
394427
395- matchedMirrorScopes := map [string ]struct {}{}
396- for _ , scope := range scopes {
397- policyScope := normalizeImageScope (scope )
398- if policyScope == "" {
399- continue
400- }
428+ matchedMirrors := collectMatchedMirrorScopes (scopes , normalizedMirrors )
429+ if len (matchedMirrors ) == 0 {
430+ continue
431+ }
401432
402- for _ , mirrorScope := range mirrorScopes {
403- if clusterImagePolicyScopeMatchesMirror (policyScope , mirrorScope ) {
404- matchedMirrorScopes [normalizeImageScope (mirrorScope )] = struct {}{}
405- }
406- }
433+ match := policyMatch {
434+ name : policy .GetName (),
435+ keyData : keyData ,
436+ signedPrefix : signedPrefix ,
407437 }
408- if len (matchedMirrorScopes ) == 0 {
409- continue
438+ for _ , mirror := range matchedMirrors {
439+ if existing , found := matchByMirror [mirror ]; found {
440+ return nil , fmt .Errorf (
441+ "mirror scope %s matched multiple ClusterImagePolicies: %s, %s" ,
442+ mirror , existing .name , policy .GetName (),
443+ )
444+ }
445+ matchByMirror [mirror ] = match
410446 }
447+ }
411448
412- sortedMirrors := sortedSetKeys (matchedMirrorScopes )
449+ if len (matchByMirror ) == 0 {
450+ return nil , nil
451+ }
413452
414- mappings := make ([]RegistryMapping , 0 , len (sortedMirrors ))
415- for _ , m := range sortedMirrors {
416- mappings = append (mappings , RegistryMapping {
417- Mirror : m ,
418- Source : sourceByMirror [m ],
419- })
420- }
453+ sortedMirrors := make ([]string , 0 , len (matchByMirror ))
454+ for mirror := range matchByMirror {
455+ sortedMirrors = append (sortedMirrors , mirror )
456+ }
457+ sort .Strings (sortedMirrors )
421458
422- matches = append (matches , fmt .Sprintf ("%s (%s)" , policy .GetName (), strings .Join (sortedMirrors , ", " )))
423- match = & SigstorePolicyInfo {
424- RegistryMappings : mappings ,
425- CosignKeyData : keyData ,
426- SignedPrefix : signedPrefix ,
427- }
459+ firstMatch := matchByMirror [sortedMirrors [0 ]]
460+ match := & SigstorePolicyInfo {
461+ RegistryMappings : make ([]RegistryMapping , 0 , len (sortedMirrors )),
462+ CosignKeyData : firstMatch .keyData ,
428463 }
429464
430- if len (matches ) > 1 {
431- sort .Strings (matches )
432- return nil , fmt .Errorf (
433- "expected exactly one ClusterImagePolicy matching mirror registries, found %d: %s" ,
434- len (matches ), strings .Join (matches , ", " ),
435- )
465+ for _ , mirror := range sortedMirrors {
466+ mirrorMatch := matchByMirror [mirror ]
467+ if match .CosignKeyData != mirrorMatch .keyData {
468+ return nil , fmt .Errorf (
469+ "matched ClusterImagePolicies use different cosign key data and cannot be combined: %s, %s" ,
470+ firstMatch .name , mirrorMatch .name ,
471+ )
472+ }
473+
474+ match .RegistryMappings = append (match .RegistryMappings , RegistryMapping {
475+ Mirror : mirror ,
476+ Source : sourceByNormalizedMirror [mirror ],
477+ SignedPrefix : mirrorMatch .signedPrefix ,
478+ })
436479 }
437480
438481 return match , nil
0 commit comments