Skip to content

Commit fc5b620

Browse files
committed
fallback when vsa is not found
1 parent ccbda8d commit fc5b620

File tree

1 file changed

+62
-3
lines changed

1 file changed

+62
-3
lines changed

cmd/validate/vsa.go

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ func processVSAResult(vsaResult *vsa.ValidationResult, imgStatus *ImageStatus, d
701701
}
702702

703703
// Aggregate signature status
704+
// When SignatureVerified is false, mark as NOT VERIFIED
705+
// This covers both cases: signature verification failure and retrieval failure (no VSA to verify)
704706
if !vsaResult.SignatureVerified {
705707
data.SignatureStatus = "NOT VERIFIED"
706708
}
@@ -745,9 +747,17 @@ func aggregateAllSectionsData(allResults []vsa.ComponentResult) AllSectionsData
745747
Digest: shortDigest,
746748
}
747749

748-
// Process VSA result
750+
// Process VSA result (always process if available, even if there's an error)
749751
if result.Result != nil {
750752
processVSAResult(result.Result, &imgStatus, &data, shortDigest)
753+
} else if result.Error != nil {
754+
// If there's an error but no Result, create a status from the error
755+
reason := extractReasonFromMessage(result.Error.Error())
756+
imgStatus.VSAStatus = fmt.Sprintf("FAILED(reason=%s)", reason)
757+
data.VSAFailed++
758+
data.FallbackReasons[reason] = true
759+
// When VSA retrieval fails, signature cannot be verified
760+
data.SignatureStatus = "NOT VERIFIED"
751761
}
752762

753763
// Handle fallback
@@ -1137,17 +1147,34 @@ func processSnapshotComponentWithWorkerContext(ctx context.Context, component ap
11371147
// Extract digest from ContainerImage
11381148
digest, err := vsa.ExtractDigestFromImageRef(component.ContainerImage)
11391149
if err != nil {
1150+
// Extract digest errors don't trigger fallback (invalid input)
11401151
return createErrorResult(component, fmt.Errorf("failed to extract digest: %w", err))
11411152
}
11421153

11431154
// Perform VSA validation
11441155
result, err := performVSAValidation(ctx, digest, data)
1156+
1157+
// Create ValidationResult from error if needed (for proper display)
11451158
if err != nil {
1146-
return createErrorResult(component, fmt.Errorf("VSA validation failed: %w", err))
1159+
// Create a ValidationResult from the error for proper display
1160+
errorResult := createValidationResultFromError(err)
1161+
1162+
// Check if fallback should be triggered BEFORE returning error
1163+
if data.fallbackToImageValidation && shouldTriggerFallbackForComponent(err, errorResult) {
1164+
return handleComponentFallback(ctx, component, data, errorResult, workerFallbackContext)
1165+
}
1166+
1167+
// Return error result with ValidationResult for proper display
1168+
return vsa.ComponentResult{
1169+
ComponentName: component.Name,
1170+
ImageRef: component.ContainerImage,
1171+
Result: errorResult,
1172+
Error: fmt.Errorf("VSA validation failed: %w", err),
1173+
}
11471174
}
11481175

11491176
// Handle fallback if enabled and needed
1150-
if data.fallbackToImageValidation && shouldTriggerFallbackForComponent(err, result) {
1177+
if data.fallbackToImageValidation && shouldTriggerFallbackForComponent(nil, result) {
11511178
return handleComponentFallback(ctx, component, data, result, workerFallbackContext)
11521179
}
11531180

@@ -1232,13 +1259,45 @@ func handleComponentFallback(ctx context.Context, component app.SnapshotComponen
12321259

12331260
// createErrorResult creates a ComponentResult with an error
12341261
func createErrorResult(component app.SnapshotComponent, err error) vsa.ComponentResult {
1262+
// Create ValidationResult from error for proper display
1263+
errorResult := createValidationResultFromError(err)
12351264
return vsa.ComponentResult{
12361265
ComponentName: component.Name,
12371266
ImageRef: component.ContainerImage,
1267+
Result: errorResult,
12381268
Error: err,
12391269
}
12401270
}
12411271

1272+
// createValidationResultFromError creates a ValidationResult from an error
1273+
// This ensures proper display of VSA status even when validation fails
1274+
func createValidationResultFromError(err error) *vsa.ValidationResult {
1275+
if err == nil {
1276+
return nil
1277+
}
1278+
1279+
// Determine reason code from error message
1280+
reasonCode := "retrieval_failed"
1281+
errMsg := err.Error()
1282+
1283+
// Check for specific error types
1284+
if strings.Contains(errMsg, "timeout") || strings.Contains(errMsg, "exceeded allowed execution time") {
1285+
reasonCode = "retrieval_failed"
1286+
} else if strings.Contains(errMsg, "no entries found") || strings.Contains(errMsg, "not found") {
1287+
reasonCode = "no_vsa"
1288+
} else if strings.Contains(errMsg, "signature") {
1289+
reasonCode = "retrieval_failed"
1290+
}
1291+
1292+
return &vsa.ValidationResult{
1293+
Passed: false,
1294+
Message: errMsg,
1295+
SignatureVerified: false, // When retrieval fails, signature cannot be verified
1296+
PredicateOutcome: "",
1297+
ReasonCode: reasonCode,
1298+
}
1299+
}
1300+
12421301
// OutputFormatter defines the interface for objects that can be formatted for output
12431302
type OutputFormatter interface {
12441303
PrintJSON(writer io.Writer) error

0 commit comments

Comments
 (0)