Change behavior for installing plugin with missing .prov file (now warns and continues instead of failing)

Signed-off-by: Scott Rigby <scott@r6by.com>
pull/31176/head
Scott Rigby 4 weeks ago
parent aef38ea221
commit 0d54097d54
No known key found for this signature in database
GPG Key ID: C7C6FBB5B91C1155

@ -184,20 +184,15 @@ func (i *HTTPInstaller) PrepareForVerification() (string, func(), error) {
return "", nil, fmt.Errorf("failed to write plugin file: %w", err) return "", nil, fmt.Errorf("failed to write plugin file: %w", err)
} }
// Download signature file // Try to download signature file - don't fail if it doesn't exist
provData, err := g.Get(i.Source+".prov", getter.WithURL(i.Source+".prov")) if provData, err := g.Get(i.Source+".prov", getter.WithURL(i.Source+".prov")); err == nil {
if err != nil { if err := os.WriteFile(pluginFile+".prov", provData.Bytes(), 0644); err == nil {
cleanup() // Store the provenance data so we can save it after installation
return "", nil, fmt.Errorf("failed to download plugin signature: %w", err) i.provData = provData.Bytes()
} }
if err := os.WriteFile(pluginFile+".prov", provData.Bytes(), 0644); err != nil {
cleanup()
return "", nil, fmt.Errorf("failed to write signature file: %w", err)
} }
// Note: We don't fail if .prov file can't be downloaded - the verification logic
// Store the provenance data so we can save it after installation // in InstallWithOptions will handle missing .prov files appropriately
i.provData = provData.Bytes()
return pluginFile, cleanup, nil return pluginFile, cleanup, nil
} }

@ -100,20 +100,32 @@ func InstallWithOptions(i Installer, opts Options) (*VerificationResult, error)
defer cleanup() defer cleanup()
} }
// Verify the plugin // Check if provenance file exists
verification, err := plugin.VerifyPlugin(pluginPath, opts.Keyring) provFile := pluginPath + ".prov"
if err != nil { if _, err := os.Stat(provFile); err != nil {
return nil, fmt.Errorf("plugin verification failed: %w", err) if os.IsNotExist(err) {
} // No .prov file found - emit warning but continue installation
fmt.Fprintf(os.Stderr, "WARNING: No provenance file found for plugin. Plugin is not signed and cannot be verified.\n")
} else {
// Other error accessing .prov file
return nil, fmt.Errorf("failed to access provenance file: %w", err)
}
} else {
// Provenance file exists - verify the plugin
verification, err := plugin.VerifyPlugin(pluginPath, opts.Keyring)
if err != nil {
return nil, fmt.Errorf("plugin verification failed: %w", err)
}
// Collect verification info // Collect verification info
result = &VerificationResult{ result = &VerificationResult{
SignedBy: make([]string, 0), SignedBy: make([]string, 0),
Fingerprint: fmt.Sprintf("%X", verification.SignedBy.PrimaryKey.Fingerprint), Fingerprint: fmt.Sprintf("%X", verification.SignedBy.PrimaryKey.Fingerprint),
FileHash: verification.FileHash, FileHash: verification.FileHash,
} }
for name := range verification.SignedBy.Identities { for name := range verification.SignedBy.Identities {
result.SignedBy = append(result.SignedBy, name) result.SignedBy = append(result.SignedBy, name)
}
} }
} }

@ -190,15 +190,14 @@ func (i *LocalInstaller) PrepareForVerification() (string, func(), error) {
return "", nil, fmt.Errorf("verification not supported for directories") return "", nil, fmt.Errorf("verification not supported for directories")
} }
// For local files, we just need to check that the .prov file exists // For local files, try to read the .prov file if it exists
provFile := i.Source + ".prov" provFile := i.Source + ".prov"
provData, err := os.ReadFile(provFile) if provData, err := os.ReadFile(provFile); err == nil {
if err != nil { // Store the provenance data so we can save it after installation
return "", nil, fmt.Errorf("signature file %s not found: %w", provFile, err) i.provData = provData
} }
// Note: We don't fail if .prov file doesn't exist - the verification logic
// Store the provenance data so we can save it after installation // in InstallWithOptions will handle missing .prov files appropriately
i.provData = provData
// Return the source path directly, no cleanup needed // Return the source path directly, no cleanup needed
return i.Source, nil, nil return i.Source, nil, nil

@ -288,21 +288,18 @@ func (i *OCIInstaller) PrepareForVerification() (pluginPath string, cleanup func
return "", nil, fmt.Errorf("failed to save plugin tarball: %w", err) return "", nil, fmt.Errorf("failed to save plugin tarball: %w", err)
} }
// Download the provenance file // Try to download the provenance file - don't fail if it doesn't exist
provSource := i.Source + ".prov" provSource := i.Source + ".prov"
provData, err := i.getter.Get(provSource) if provData, err := i.getter.Get(provSource); err == nil {
if err != nil { // Save provenance to temp directory
cleanup() provFile := filepath.Join(tempDir, filename+".prov")
return "", nil, fmt.Errorf("failed to pull provenance from %s: %w", provSource, err) if err := os.WriteFile(provFile, provData.Bytes(), 0644); err == nil {
} slog.Debug("prepared plugin for verification", "plugin", pluginTarball, "provenance", provFile)
}
// Save provenance to temp directory
provFile := filepath.Join(tempDir, filename+".prov")
if err := os.WriteFile(provFile, provData.Bytes(), 0644); err != nil {
cleanup()
return "", nil, fmt.Errorf("failed to save provenance file: %w", err)
} }
// Note: We don't fail if .prov file can't be downloaded - the verification logic
// in InstallWithOptions will handle missing .prov files appropriately
slog.Debug("prepared plugin for verification", "plugin", pluginTarball, "provenance", provFile) slog.Debug("prepared plugin for verification", "plugin", pluginTarball)
return pluginTarball, cleanup, nil return pluginTarball, cleanup, nil
} }

Loading…
Cancel
Save