fix: harden connector manifest validation

This commit is contained in:
Codex
2026-06-16 23:40:33 +02:00
parent 4a4b86ae10
commit 8d6d9bf9c2
5 changed files with 289 additions and 28 deletions
+73 -1
View File
@@ -1,6 +1,9 @@
package connectorkit
import "regexp"
import (
"regexp"
"strings"
)
type Manifest struct {
SchemaVersion string `json:"schemaVersion"`
@@ -93,6 +96,7 @@ func ValidateManifest(manifest Manifest) ValidationResult {
}
if manifest.AssetType == "connector" && manifest.SchemaVersion == "attesto.connector.v2" {
findings = appendV2Findings(manifest, findings)
findings = appendPlaceholderFindings(manifest, findings)
}
score := 0
if len(findings) == 0 {
@@ -142,6 +146,15 @@ func ValidateManifest(manifest Manifest) ValidationResult {
}
func appendV2Findings(manifest Manifest, findings []Finding) []Finding {
if strings.TrimSpace(manifest.Publisher["slug"]) == "" || strings.TrimSpace(manifest.Publisher["name"]) == "" {
findings = append(findings, Finding{"publisher.invalid", "error", "publisher.slug and publisher.name are required"})
}
if strings.TrimSpace(manifest.Repository["url"]) == "" {
findings = append(findings, Finding{"repository.invalid", "error", "repository.url is required"})
}
if strings.TrimSpace(manifest.Documentation["url"]) == "" {
findings = append(findings, Finding{"documentation.invalid", "error", "documentation.url is required"})
}
if !hasRequiredKeys(manifest.Provider, []string{"id", "name", "websiteUrl"}) {
findings = append(findings, Finding{"provider.invalid", "error", "provider.id, provider.name and provider.websiteUrl are required"})
}
@@ -200,6 +213,8 @@ func appendV2Findings(manifest Manifest, findings []Finding) []Finding {
canary, ok := manifest.Runtime["canary"].(map[string]any)
if !ok || canary["status"] != "green" {
findings = append(findings, Finding{"runtime.canary", "error", "runtime.canary.status must be green before publication"})
} else if strings.TrimSpace(toString(canary["ref"])) == "" {
findings = append(findings, Finding{"runtime.canary_ref", "error", "runtime.canary.ref must point to real canary or release evidence"})
}
}
if !hasRequiredKeys(manifest.InstallRequirements, []string{"tenantLoginRequired", "entitlementRequired"}) {
@@ -213,6 +228,63 @@ func appendV2Findings(manifest Manifest, findings []Finding) []Finding {
return findings
}
func appendPlaceholderFindings(manifest Manifest, findings []Finding) []Finding {
fields := map[string]any{
"publisher": manifest.Publisher,
"repository": manifest.Repository,
"documentation": manifest.Documentation,
"provider": manifest.Provider,
"runtime": manifest.Runtime,
}
for field, value := range fields {
if containsPlaceholder(value) {
findings = append(findings, Finding{
Code: "manifest.placeholder",
Severity: "error",
Message: field + " contains placeholder/example metadata; production connector manifests require real values",
})
}
}
return findings
}
func containsPlaceholder(value any) bool {
switch typed := value.(type) {
case string:
normalized := strings.ToLower(strings.TrimSpace(typed))
for _, marker := range []string{"change me", "change-me", "change_me", "example.com", "example.org", "example.net"} {
if strings.Contains(normalized, marker) {
return true
}
}
case map[string]string:
for _, nested := range typed {
if containsPlaceholder(nested) {
return true
}
}
case map[string]any:
for _, nested := range typed {
if containsPlaceholder(nested) {
return true
}
}
case []string:
for _, nested := range typed {
if containsPlaceholder(nested) {
return true
}
}
case []any:
for _, nested := range typed {
if containsPlaceholder(nested) {
return true
}
}
}
return false
}
func hasRequiredKeys(value map[string]any, keys []string) bool {
if value == nil {
return false