// BreakPilot Compliance SDK - Security Scanner Service // // Orchestrates security scanning tools and aggregates results. package main import ( "context" "net/http" "os" "os/signal" "syscall" "time" "github.com/breakpilot/compliance-sdk/services/security-scanner/internal/api" "github.com/breakpilot/compliance-sdk/services/security-scanner/internal/scanner" "github.com/gin-gonic/gin" "go.uber.org/zap" ) func main() { logger, _ := zap.NewProduction() defer logger.Sync() // Initialize scanner manager scannerManager := scanner.NewManager(logger) if os.Getenv("ENVIRONMENT") == "production" { gin.SetMode(gin.ReleaseMode) } router := gin.New() router.Use(gin.Recovery()) // Health check router.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status": "healthy", "service": "security-scanner", "tools": scannerManager.AvailableTools(), }) }) // API routes v1 := router.Group("/api/v1") { // Scanning v1.POST("/scan", api.StartScan(scannerManager)) v1.GET("/scan/:scanId", api.GetScanStatus(scannerManager)) v1.GET("/scan/:scanId/results", api.GetScanResults(scannerManager)) // Findings v1.GET("/findings", api.GetFindings(scannerManager)) v1.GET("/findings/:findingId", api.GetFinding(scannerManager)) v1.PUT("/findings/:findingId/status", api.UpdateFindingStatus(scannerManager)) // SBOM v1.POST("/sbom/generate", api.GenerateSBOM(scannerManager)) v1.GET("/sbom/:sbomId", api.GetSBOM(scannerManager)) v1.GET("/sbom/:sbomId/export/:format", api.ExportSBOM(scannerManager)) // Recommendations v1.GET("/recommendations", api.GetRecommendations(scannerManager)) // Tool status v1.GET("/tools", api.GetToolsStatus(scannerManager)) } port := os.Getenv("PORT") if port == "" { port = "8083" } srv := &http.Server{ Addr: ":" + port, Handler: router, ReadTimeout: 15 * time.Second, WriteTimeout: 300 * time.Second, // Long timeout for scans } go func() { logger.Info("Starting Security Scanner", zap.String("port", port)) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Fatal("Failed to start server", zap.Error(err)) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("Shutting down...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() srv.Shutdown(ctx) }