Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ Result and summary `GetStatus` methods carry the effective substatus through
rule, control, resource, framework, and top-level views. Summary substatuses
are derived from serialized control status information, so this does not add a
new report field.

### Scan request control exclusions

`httpserver/meta/v1.PostScanRequest` accepts optional `excludeControls`, a list of
control IDs (or legacy CIS section numbers), for example `["C-0069", "C-0070"]`.
Scanners supporting this field omit matching controls before evaluation and
compliance scoring, using the CLI's `--exclude-controls` behavior. Omitting the
field or using an empty list preserves the selected assessment scope. Exclusions
narrow that scope; they do not establish that the excluded checks would pass.
3 changes: 3 additions & 0 deletions httpserver/meta/v1/datastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type PostScanRequest struct {
//
// Example: ["armo-system", "kube-system"]
ExcludedNamespaces []string `json:"excludedNamespaces,omitempty"`
// Controls to exclude from evaluation and compliance scoring in every selected framework.
// Same as `kubescape scan --exclude-controls`: control IDs or legacy CIS section numbers.
ExcludeControls []string `json:"excludeControls,omitempty"`
// Namespaces to include.
//
// Same as `kubescape scan --include-namespaces`.
Expand Down
45 changes: 45 additions & 0 deletions httpserver/meta/v1/datastructure_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package v1

import (
"encoding/json"
"testing"
)

func TestPostScanRequestPreservesControlExclusions(t *testing.T) {
var request PostScanRequest
input := []byte(`{"targetType":"framework","targetNames":["nsa"],"excludeControls":["C-0069","C-0070"]}`)
if err := json.Unmarshal(input, &request); err != nil {
t.Fatal(err)
}
output, err := json.Marshal(request)
if err != nil {
t.Fatal(err)
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(output, &fields); err != nil {
t.Fatal(err)
}
if string(fields["excludeControls"]) != `["C-0069","C-0070"]` {
t.Fatalf("control exclusions lost in request round-trip: %s", output)
}
}

func TestPostScanRequestOmitsEmptyControlExclusions(t *testing.T) {
for _, input := range []string{`{}`, `{"excludeControls":[]}`, `{"excludeControls":null}`} {
var request PostScanRequest
if err := json.Unmarshal([]byte(input), &request); err != nil {
t.Fatal(err)
}
output, err := json.Marshal(request)
if err != nil {
t.Fatal(err)
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(output, &fields); err != nil {
t.Fatal(err)
}
if _, exists := fields["excludeControls"]; exists {
t.Fatalf("empty exclusions must be omitted: %s", output)
}
}
}
Loading