@@ -40,6 +40,63 @@ import (
4040 _ "github.com/kopexa-grc/kspec/provider/all"
4141)
4242
43+ // ---------------------------------------------------------------------------
44+ // Disabled queries (per asset)
45+ // ---------------------------------------------------------------------------
46+
47+ // disabledQueries maps asset fingerprints to query UIDs that should be skipped.
48+ // In production, this would come from a database or API.
49+ var disabledQueries = map [string ][]string {
50+ AssetFingerprint ("network" , "host" , "example.com" ): {"tls-cert-not-expiring" },
51+ AssetFingerprint ("network" , "host" , "cloudflare.com" ): {"tls-modern-version" , "tls-cert-not-expiring" },
52+ }
53+
54+ // filterDisabledQueries returns a deep copy of the policies with checks matching
55+ // the disabled UIDs removed from both Groups[].Checks and top-level Queries.
56+ // The original slice is not modified so it can be reused across integrations.
57+ func filterDisabledQueries (policies []policy.Policy , disabled []string ) []policy.Policy {
58+ if len (disabled ) == 0 {
59+ return policies
60+ }
61+
62+ set := make (map [string ]struct {}, len (disabled ))
63+ for _ , uid := range disabled {
64+ set [uid ] = struct {}{}
65+ }
66+
67+ out := make ([]policy.Policy , len (policies ))
68+ copy (out , policies )
69+
70+ for i , p := range out {
71+ // Filter groups and their checks.
72+ var groups []policy.Group
73+ for _ , g := range p .Groups {
74+ var checks []policy.Check
75+ for _ , c := range g .Checks {
76+ if _ , skip := set [c .UID ]; ! skip {
77+ checks = append (checks , c )
78+ }
79+ }
80+ if len (checks ) > 0 {
81+ g .Checks = checks
82+ groups = append (groups , g )
83+ }
84+ }
85+ out [i ].Groups = groups
86+
87+ // Filter top-level queries.
88+ var queries []policy.Check
89+ for _ , q := range p .Queries {
90+ if _ , skip := set [q .UID ]; ! skip {
91+ queries = append (queries , q )
92+ }
93+ }
94+ out [i ].Queries = queries
95+ }
96+
97+ return out
98+ }
99+
43100// ---------------------------------------------------------------------------
44101// Asset Store
45102// ---------------------------------------------------------------------------
@@ -136,13 +193,14 @@ type IntegrationResult struct {
136193 ResourceTypes int
137194 TotalResources int
138195 // Scan
139- Score uint32
140- Grade string
141- RiskLevel string
142- Findings scoring.Findings
143- Duration time.Duration
144- Phase string // "discovery", "sync", "scan", "complete"
145- Err error
196+ Score uint32
197+ Grade string
198+ RiskLevel string
199+ Findings scoring.Findings
200+ DisabledCount int // Number of queries disabled for this asset
201+ Duration time.Duration
202+ Phase string // "discovery", "sync", "scan", "complete"
203+ Err error
146204}
147205
148206// ---------------------------------------------------------------------------
@@ -309,6 +367,15 @@ func processIntegration(ctx context.Context, store AssetStore, integration Integ
309367 return result
310368 }
311369
370+ // Apply per-asset disabled queries.
371+ if disabled , ok := disabledQueries [fingerprint ]; ok {
372+ policies = filterDisabledQueries (policies , disabled )
373+ result .DisabledCount = len (disabled )
374+
375+ fmt .Fprintf (os .Stderr , "[%s] Disabled %d queries for asset %s: %v\n " ,
376+ integration .ID , len (disabled ), integration .AssetName , disabled )
377+ }
378+
312379 s := scanner .NewScanner (scanner.ScanConfig {
313380 ProviderName : integration .Provider ,
314381 ProviderConfig : integration .Config ,
@@ -433,8 +500,8 @@ func main() {
433500 fmt .Println ("=== Results ===" )
434501 fmt .Println ()
435502
436- header := fmt .Sprintf ("%-34s %-18s %6s %6s %-10s %4s %4s %4s %4s %10s %-10s" ,
437- "Fingerprint" , "Asset" , "ResTyp" , "ResAll" , "Grade" , "Crit" , "High" , "Med" , "Low" , "Duration" , "Phase" )
503+ header := fmt .Sprintf ("%-34s %-18s %6s %6s %-10s %4s %4s %4s %4s %4s % 10s %-10s" ,
504+ "Fingerprint" , "Asset" , "ResTyp" , "ResAll" , "Grade" , "Skip" , " Crit" , "High" , "Med" , "Low" , "Duration" , "Phase" )
438505 fmt .Println (header )
439506 fmt .Println (strings .Repeat ("-" , len (header )))
440507
@@ -444,10 +511,10 @@ func main() {
444511 if r .Err != nil {
445512 failed ++
446513
447- fmt .Printf ("%-34s %-18s %6s %6s %-10s %4s %4s %4s %4s %10s %-10s ERR: %v\n " ,
514+ fmt .Printf ("%-34s %-18s %6s %6s %-10s %4s %4s %4s %4s %4s % 10s %-10s ERR: %v\n " ,
448515 truncate (r .Fingerprint , 34 ),
449516 truncate (r .Asset , 18 ),
450- "-" , "-" , "-" , "-" , "-" , "-" , "-" ,
517+ "-" , "-" , "-" , "-" , "-" , "-" , "-" , "-" ,
451518 r .Duration .Truncate (time .Millisecond ),
452519 r .Phase ,
453520 r .Err ,
@@ -458,12 +525,13 @@ func main() {
458525
459526 succeeded ++
460527
461- fmt .Printf ("%-34s %-18s %6d %6d %-10s %4d %4d %4d %4d %10s %-10s\n " ,
528+ fmt .Printf ("%-34s %-18s %6d %6d %-10s %4d %4d %4d %4d %4d % 10s %-10s\n " ,
462529 truncate (r .Fingerprint , 34 ),
463530 truncate (r .Asset , 18 ),
464531 r .ResourceTypes ,
465532 r .TotalResources ,
466533 fmt .Sprintf ("%s (%d)" , r .Grade , r .Score ),
534+ r .DisabledCount ,
467535 r .Findings .Critical ,
468536 r .Findings .High ,
469537 r .Findings .Medium ,
0 commit comments