The CleanStart Source Intelligence Core SDK for Go provides programmatic access to vulnerability data, package metadata, and supply chain intelligence. Query CVEs, track fix status, and monitor dependencies in your Go projects.
Installation
Add the module to your Go project using go get github.com/cleanstart/intelligence-go. Verify installation by running go list -m github.com/cleanstart/intelligence-go. Update to the latest version using go get -u github.com/cleanstart/intelligence-go.
Configuration
Set your API key as an environment variable with export CLEANSTART_API_KEY="your-api-key-here". Alternatively, pass it when creating the client as shown below.
import "github.com/cleanstart/intelligence-go" client := intelligence.NewClient( intelligence.WithAPIKey("your-api-key-here"),)To obtain an API key, visit dashboard.cleanstart.com and follow these steps. First, log in to your account. Next, navigate to Settings > API Keys. Then click Generate New Key. Select the scope Source Intelligence Read (minimum). Finally, copy the key and store it securely.
First Query
Query vulnerabilities by CVE ID using the code below.
package main import ( "context" "fmt" "log" "github.com/cleanstart/intelligence-go") func main() { client := intelligence.NewClient() ctx := context.Background() // Query CVE vuln, err := client.Vulnerabilities.GetByCVEID(ctx, "CVE-2024-1234") if err != nil { log.Fatal(err) } fmt.Printf("CVE: %s\n", vuln.CVEID) fmt.Printf("Severity: %s\n", vuln.Severity) fmt.Printf("CVSS Score: %.1f\n", vuln.CVSSScore) fmt.Printf("Description: %s\n", vuln.Description)}Querying Vulnerabilities
By CVE ID
vuln, err := client.Vulnerabilities.GetByCVEID(ctx, "CVE-2024-1234")if err != nil { log.Fatal(err)} fmt.Printf("CVEID: %s\n", vuln.CVEID)fmt.Printf("Severity: %s\n", vuln.Severity)fmt.Printf("CVSS Score: %.1f\n", vuln.CVSSScore)fmt.Printf("Description: %s\n", vuln.Description)By Package Name
vulns, err := client.Vulnerabilities.GetByPackage(ctx, &intelligence.PackageQuery{ Name: "django", Ecosystem: "pypi", Limit: 10,})if err != nil { log.Fatal(err)} for _, vuln := range vulns.Results { fmt.Printf("%s: %s\n", vuln.CVEID, vuln.Description)}By Ecosystem
vulns, err := client.Vulnerabilities.GetByEcosystem(ctx, &intelligence.EcosystemQuery{ Ecosystem: "npm", Severity: "HIGH", Limit: 50,})if err != nil { log.Fatal(err)} fmt.Printf("Found %d HIGH severity vulnerabilities\n", len(vulns.Results))for _, vuln := range vulns.Results { fmt.Printf("- %s: %v\n", vuln.CVEID, vuln.AffectedPackages)}Advanced Filtering
vulns, err := client.Vulnerabilities.Search(ctx, &intelligence.VulnerabilityFilter{ SeverityMin: "HIGH", CVSSScoreMin: 7.0, HasFix: true, PublishedAfter: "2024-01-01", Pagination: &intelligence.Pagination{ Page: 1, Limit: 20, },})if err != nil { log.Fatal(err)} fmt.Printf("Total results: %d\n", vulns.Pagination.Total)fmt.Printf("Page: %d of %d\n", vulns.Pagination.Page, vulns.Pagination.Pages) for _, vuln := range vulns.Results { // Process vulnerability}Paginated Results
// Iterate through all pagesfilter := &intelligence.VulnerabilityFilter{ SeverityMin: "HIGH",} for page := 1; page <= 100; page++ { filter.Pagination = &intelligence.Pagination{ Page: page, Limit: 100, } results, err := client.Vulnerabilities.Search(ctx, filter) if err != nil { log.Fatal(err) } for _, vuln := range results.Results { // Process each vulnerability } if !results.Pagination.HasNext { break }}Package and Version Information
Get Package Metadata
pkg, err := client.Packages.GetMetadata(ctx, &intelligence.PackageQuery{ Name: "requests", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} fmt.Printf("Name: %s\n", pkg.Name)fmt.Printf("Latest version: %s\n", pkg.LatestVersion)fmt.Printf("Repository: %s\n", pkg.RepositoryURL)fmt.Printf("License: %s\n", pkg.License)Check if Vulnerability is Fixed
isFixed, err := client.Packages.IsVulnerabilityFixed(ctx, &intelligence.FixStatusQuery{ PackageName: "django", Ecosystem: "pypi", Version: "4.2.8", CVEID: "CVE-2024-1234",})if err != nil { log.Fatal(err)} if isFixed { fmt.Println("Vulnerability is fixed in Django 4.2.8")} else { fmt.Println("Upgrade required")}Get Version History
versions, err := client.Packages.GetVersions(ctx, &intelligence.PackageQuery{ Name: "requests", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} for _, version := range versions.Results { if len(version.Vulnerabilities) > 0 { fmt.Printf("%s: %d vulnerabilities\n", version.Version, len(version.Vulnerabilities)) } else { fmt.Printf("%s: Clean\n", version.Version) }}Find Latest Safe Version
safeVersion, err := client.Packages.GetLatestSafeVersion(ctx, &intelligence.PackageQuery{ Name: "requests", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} if safeVersion != "" { fmt.Printf("Latest safe version: %s\n", safeVersion)} else { fmt.Println("No safe version found")}Dependency Graph Traversal
Get Package Dependencies
deps, err := client.Dependencies.GetDependencies(ctx, &intelligence.DependencyQuery{ PackageName: "django", Version: "4.2.0", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} for _, dep := range deps.Results { fmt.Printf("- %s %s\n", dep.PackageName, dep.VersionSpec)}Get Transitive Dependencies
allDeps, err := client.Dependencies.GetTransitiveDependencies(ctx, &intelligence.DependencyQuery{ PackageName: "requests", Version: "2.31.0", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} for _, dep := range allDeps.Results { path := strings.Join(dep.Path, " -> ") fmt.Printf("%s (version: %s)\n", path, dep.Version)}Find Vulnerabilities in Dependency Tree
vulnsInDeps, err := client.Dependencies.FindVulnerabilitiesInTree(ctx, &intelligence.DependencyQuery{ PackageName: "django", Version: "4.2.0", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} for _, vuln := range vulnsInDeps.Results { path := strings.Join(vuln.Path, " -> ") fmt.Printf("Vulnerability: %s\n", vuln.CVEID) fmt.Printf("Path: %s\n", path) fmt.Printf("Severity: %s\n\n", vuln.Severity)}Exploit Prediction Scoring (EPSS)
Get EPSS Score
epss, err := client.Vulnerabilities.GetEPSS(ctx, "CVE-2024-1234")if err != nil { log.Fatal(err)} fmt.Printf("EPSS Score: %.2f\n", epss.Score) // 0.0 to 1.0fmt.Printf("Percentile: %d\n", epss.Percentile) // 0-100fmt.Printf("Severity: %s\n", epss.Severity) if epss.Score > 0.5 { fmt.Println("High exploit probability - prioritize patching")}Batch EPSS Lookup
cveIDs := []string{ "CVE-2024-1234", "CVE-2024-5678", "CVE-2024-9999",} epssData, err := client.Vulnerabilities.GetEPSSBatch(ctx, cveIDs)if err != nil { log.Fatal(err)} for cveID, epss := range epssData { fmt.Printf("%s: %.2f (percentile: %d)\n", cveID, epss.Score, epss.Percentile)}Advisory Subscriptions
Get Security Advisories
advisories, err := client.Advisories.GetByPackage(ctx, &intelligence.PackageQuery{ Name: "django", Ecosystem: "pypi",})if err != nil { log.Fatal(err)} for _, advisory := range advisories.Results { fmt.Printf("Title: %s\n", advisory.Title) fmt.Printf("Description: %s\n", advisory.Description) fmt.Printf("Affected versions: %v\n", advisory.AffectedVersions) fmt.Printf("Fixed version: %s\n", advisory.FixedVersion) fmt.Printf("Published: %s\n\n", advisory.PublishedDate)}Register Webhook
webhook, err := client.Webhooks.Register(ctx, &intelligence.WebhookConfig{ URL: "https://your-app.example.com/webhooks/advisories", Events: []string{ "advisory.created", "advisory.updated", }, Packages: []*intelligence.PackageSpec{ {Name: "django", Ecosystem: "pypi"}, {Name: "requests", Ecosystem: "pypi"}, },})if err != nil { log.Fatal(err)} fmt.Printf("Webhook ID: %s\n", webhook.ID)fmt.Printf("Endpoint: %s\n", webhook.URL)fmt.Printf("Created: %s\n", webhook.CreatedAt)Verify Webhook Signature
import ( "crypto/hmac" "crypto/sha256" "encoding/hex") func verifyWebhookSignature(secret string, payload []byte, signature string) bool { h := hmac.New(sha256.New, []byte(secret)) h.Write(payload) expected := hex.EncodeToString(h.Sum(nil)) return hmac.Equal([]byte(signature), []byte(expected))} // In your webhook handlerfunc handleWebhook(w http.ResponseWriter, r *http.Request) { signature := r.Header.Get("X-Signature") payload, _ := ioutil.ReadAll(r.Body) if !verifyWebhookSignature(os.Getenv("WEBHOOK_SECRET"), payload, signature) { http.Error(w, "Invalid signature", http.StatusUnauthorized) return } var advisory intelligence.Advisory json.Unmarshal(payload, &advisory) // Process advisory w.WriteHeader(http.StatusOK)}Response Types
Vulnerability Struct
type Vulnerability struct { CVEID string Description string Severity string CVSSScore float64 AffectedPackages []Package FixAvailable bool FixedVersion string DisclosureDate string PublishedDate string LastModifiedDate string}Package Struct
type Package struct { Name string Ecosystem string LatestVersion string RepositoryURL string Description string License string Vulnerabilities []Vulnerability}Paginated Response
type PaginatedResults struct { Results []T Pagination struct { Page int Limit int Total int Pages int HasNext bool }}Error Handling
Error Types
import "github.com/cleanstart/intelligence-go" switch err := err.(type) {case nil: // Success case *intelligence.NotFoundError: log.Printf("Resource not found: %v", err) case *intelligence.RateLimitError: log.Printf("Rate limited. Retry after: %d seconds", err.RetryAfter) case *intelligence.ValidationError: log.Printf("Invalid input: %v", err) case *intelligence.AuthenticationError: log.Printf("Authentication failed: %v", err) default: log.Printf("API error: %v", err)}Retry Logic with Exponential Backoff
import "github.com/cenkalti/backoff/v4" func queryWithRetry(ctx context.Context, cveID string) (*intelligence.Vulnerability, error) { var vuln *intelligence.Vulnerability err := backoff.Retry( func() error { var err error vuln, err = client.Vulnerabilities.GetByCVEID(ctx, cveID) return err }, backoff.WithContext(backoff.NewExponentialBackOff(), ctx), ) return vuln, err}Bulk Operations
Batch Query Multiple CVEs
cveIDs := []string{ "CVE-2024-1234", "CVE-2024-5678", "CVE-2024-9999",} results, err := client.Vulnerabilities.GetBatch(ctx, cveIDs)if err != nil { log.Fatal(err)} for cveID, vuln := range results { if vuln != nil { fmt.Printf("%s: %s\n", cveID, vuln.Severity) } else { fmt.Printf("%s: Not found\n", cveID) }}Scan Go Module Dependencies
import ( "golang.org/x/mod/modfile") func scanGoMod(modFilePath string) ([]Vulnerability, error) { data, _ := os.ReadFile(modFilePath) modFile, _ := modfile.Parse("go.mod", data, nil) var vulns []Vulnerability for _, req := range modFile.Require { vulnList, err := client.Vulnerabilities.GetByPackage(ctx, &intelligence.PackageQuery{ Name: req.Mod.Path, Ecosystem: "go", }) if err != nil { continue } for _, vuln := range vulnList.Results { vulns = append(vulns, Vulnerability{ Package: req.Mod.Path, Version: req.Mod.Version, CVEID: vuln.CVEID, Severity: vuln.Severity, }) } } return vulns, nil} vulns, _ := scanGoMod("go.mod")for _, v := range vulns { fmt.Printf("%s@%s: %s\n", v.Package, v.Version, v.CVEID)}Logging and Debugging
Enable Debug Logging
import "github.com/cleanstart/intelligence-go" client := intelligence.NewClient( intelligence.WithDebug(true), intelligence.WithLogger(log.New(os.Stderr, "", log.LstdFlags)),)Custom HTTP Transport
import "net/http" transport := &http.Transport{ MaxIdleConns: 100, MaxIdleConnsPerHost: 100, MaxConnsPerHost: 100,} httpClient := &http.Client{ Transport: transport, Timeout: 30 * time.Second,} client := intelligence.NewClient( intelligence.WithHTTPClient(httpClient),)Rate Limiting and Quotas
Default rate limits are 1,000 requests per minute, 10,000 requests per hour, and 100,000 requests per day.
Rate limit headers are available in response metadata:
vuln, err := client.Vulnerabilities.GetByCVEID(ctx, "CVE-2024-1234")if err == nil { fmt.Printf("Rate limit remaining: %d\n", vuln.RateLimitRemaining) fmt.Printf("Rate limit reset: %s\n", vuln.RateLimitReset)}Caching
The SDK includes optional caching:
client := intelligence.NewClient( intelligence.WithCacheTTL(3600 * time.Second),) // First call hits APIvuln1, _ := client.Vulnerabilities.GetByCVEID(ctx, "CVE-2024-1234") // Second call uses cachevuln2, _ := client.Vulnerabilities.GetByCVEID(ctx, "CVE-2024-1234") // Clear cacheclient.ClearCache() // Disable cache for specific queryvuln3, _ := client.Vulnerabilities.GetByCVEID( context.WithValue(ctx, "no-cache", true), "CVE-2024-1234",)Examples
Vulnerability Severity Report
func generateSeverityReport(ecosystem string) error { ctx := context.Background() severities := []string{"CRITICAL", "HIGH", "MEDIUM", "LOW"} report := make(map[string]int) for _, severity := range severities { vulns, err := client.Vulnerabilities.GetByEcosystem(ctx, &intelligence.EcosystemQuery{ Ecosystem: ecosystem, Severity: severity, }) if err != nil { return err } report[severity] = len(vulns.Results) } for severity, count := range report { fmt.Printf("%s: %d\n", severity, count) } return nil}Dependency Security Audit
type AuditResult struct { Package string Version string VulnerabilityCount int CriticalCount int HighCount int UpdateAvailable bool LatestVersion string} func auditDependency(ctx context.Context, pkgName, version string) (*AuditResult, error) { // Get vulnerabilities for current version vulns, err := client.Vulnerabilities.GetByPackage(ctx, &intelligence.PackageQuery{ Name: pkgName, Ecosystem: "go", }) if err != nil { return nil, err } // Count by severity critical := 0 high := 0 for _, v := range vulns.Results { if v.Severity == "CRITICAL" { critical++ } else if v.Severity == "HIGH" { high++ } } // Check for updates pkg, _ := client.Packages.GetMetadata(ctx, &intelligence.PackageQuery{ Name: pkgName, Ecosystem: "go", }) updateAvailable := version != pkg.LatestVersion return &AuditResult{ Package: pkgName, Version: version, VulnerabilityCount: len(vulns.Results), CriticalCount: critical, HighCount: high, UpdateAvailable: updateAvailable, LatestVersion: pkg.LatestVersion, }, nil}Webhook Server
import ( "encoding/json" "net/http") func handleAdvisoryWebhook(w http.ResponseWriter, r *http.Request) { // Verify signature signature := r.Header.Get("X-Signature") payload, _ := io.ReadAll(r.Body) if !verifyWebhookSignature(os.Getenv("WEBHOOK_SECRET"), payload, signature) { http.Error(w, "Invalid signature", http.StatusUnauthorized) return } // Parse webhook payload var event map[string]interface{} json.Unmarshal(payload, &event) // Log advisory log.Printf("Advisory event: %s\n", event["event"]) log.Printf("CVE: %s\n", event["advisory"].(map[string]interface{})["cve_id"]) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"status": "received"})} func main() { http.HandleFunc("/webhooks/advisories", handleAdvisoryWebhook) http.ListenAndServe(":8080", nil)}Next Steps
API Reference: See Source Intelligence Core API docs for complete endpoint documentation (internal use). Authentication: Learn about API key management. Examples: Explore integration samples for common Go patterns. GitHub: View source code on GitHub.
