Repository: aquasecurity/starboard
Pull request #191 (2020-10-09 21:52:06)

refactor: Bump up kube-bench to v0.4.0
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=h1) Report
> Merging [#191](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=desc) into [master](https://codecov.io/gh/aquasecurity/starboard/commit/eb2e822688cd50823583c8ab82d41d5a23b3fd57?el=desc) will **decrease** coverage by `0.15%`.
> The diff coverage is `12.85%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/191/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb)](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #191      +/-   ##
==========================================
- Coverage   16.21%   16.05%   -0.16%     
==========================================
  Files          35       36       +1     
  Lines        1776     1806      +30     
==========================================
+ Hits          288      290       +2     
- Misses       1453     1479      +26     
- Partials       35       37       +2     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/cmd/find\_vulnerabilities.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2NtZC9maW5kX3Z1bG5lcmFiaWxpdGllcy5nbw==) | `0.00% <0.00%> (ø)` | |
| [pkg/cmd/kube\_bench.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2NtZC9rdWJlX2JlbmNoLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/find/vulnerabilities/trivy/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2ZpbmQvdnVsbmVyYWJpbGl0aWVzL3RyaXZ5L3NjYW5uZXIuZ28=) | `0.00% <0.00%> (ø)` | |
| [pkg/kube/cr\_manager.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2t1YmUvY3JfbWFuYWdlci5nbw==) | `0.00% <0.00%> (ø)` | |
| [pkg/kubebench/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2t1YmViZW5jaC9zY2FubmVyLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/operator/etc/config.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL29wZXJhdG9yL2V0Yy9jb25maWcuZ28=) | `69.56% <0.00%> (-3.17%)` | :arrow_down: |
| [pkg/starboard/config.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL3N0YXJib2FyZC9jb25maWcuZ28=) | `0.00% <0.00%> (ø)` | |
| [pkg/find/vulnerabilities/trivy/converter.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2ZpbmQvdnVsbmVyYWJpbGl0aWVzL3RyaXZ5L2NvbnZlcnRlci5nbw==) | `78.94% <60.00%> (-1.88%)` | :arrow_down: |
| [pkg/kubebench/converter.go](https://codecov.io/gh/aquasecurity/starboard/pull/191/diff?src=pr&el=tree#diff-cGtnL2t1YmViZW5jaC9jb252ZXJ0ZXIuZ28=) | `93.33% <75.00%> (-6.67%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=footer). Last update [eb2e822...35cab73](https://codecov.io/gh/aquasecurity/starboard/pull/191?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/cmd/starboard-operator/main.go b/cmd/starboard-operator/main.go
index 4c71352..75b4f62 100644
--- a/cmd/starboard-operator/main.go
+++ b/cmd/starboard-operator/main.go
@@ -3,6 +3,7 @@ package main
 import (
 	"errors"
 	"fmt"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 
 	"sigs.k8s.io/controller-runtime/pkg/healthz"
 
@@ -44,7 +45,7 @@ var (
 )
 
 var (
-	versionInfo = etc.VersionInfo{
+	versionInfo = starboard.BuildInfo{
 		Version: version,
 		Commit:  commit,
 		Date:    date,
@@ -199,7 +200,7 @@ func getEnabledScanner(config etc.Config) (scanner.VulnerabilityScanner, error)
 		return nil, fmt.Errorf("invalid configuration: none vulnerability scanner enabled")
 	}
 	if config.ScannerTrivy.Enabled {
-		setupLog.Info("Using Trivy as vulnerability scanner", "version", config.ScannerTrivy.Version)
+		setupLog.Info("Using Trivy as vulnerability scanner", "image", config.ScannerTrivy.ImageRef)
 		return trivy.NewScanner(config.ScannerTrivy), nil
 	}
 	if config.ScannerAquaCSP.Enabled {
diff --git a/cmd/starboard/main.go b/cmd/starboard/main.go
index bae080e..2b0dd4f 100644
--- a/cmd/starboard/main.go
+++ b/cmd/starboard/main.go
@@ -4,6 +4,8 @@ import (
 	"fmt"
 	"os"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"k8s.io/klog"
 
 	"github.com/aquasecurity/starboard/pkg/cmd"
@@ -23,7 +25,7 @@ func main() {
 	defer klog.Flush()
 	klog.InitFlags(nil)
 
-	version := cmd.VersionInfo{Version: version, Commit: commit, Date: date}
+	version := starboard.BuildInfo{Version: version, Commit: commit, Date: date}
 	if err := cmd.Run(version, os.Args, os.Stdout, os.Stderr); err != nil {
 		_, _ = fmt.Fprintf(os.Stderr, "error: %v\n", err)
 		os.Exit(1)
diff --git a/hack/tools.go b/hack/tools.go
index 7ebb62a..bc3fa5c 100644
--- a/hack/tools.go
+++ b/hack/tools.go
@@ -4,6 +4,6 @@
 package tools
 
 import (
-	_ "k8s.io/code-generator"
 	_ "github.com/onsi/ginkgo/ginkgo"
+	_ "k8s.io/code-generator"
 )
diff --git a/kube/init/starboard-cm.yaml b/kube/init/starboard-cm.yaml
index b0220ef..40ecff2 100644
--- a/kube/init/starboard-cm.yaml
+++ b/kube/init/starboard-cm.yaml
@@ -8,6 +8,7 @@ metadata:
 data:
   trivy.severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
   trivy.imageRef: docker.io/aquasec/trivy:0.9.1
+  kube-bench.imageRef: docker.io/aquasec/kube-bench:0.4.0
   polaris.config.yaml: |
     checks:
       # reliability
diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go
index 85b2405..bdf974d 100644
--- a/pkg/cmd/config.go
+++ b/pkg/cmd/config.go
@@ -3,19 +3,18 @@ package cmd
 import (
 	"context"
 	"fmt"
-	"github.com/aquasecurity/starboard/pkg/kube"
 	"io"
 	"strings"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/spf13/cobra"
-	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/kubernetes"
 )
 
 type LocalFlags struct {
-	get string
+	get      string
 	nameOnly bool
 }
 
@@ -26,19 +25,19 @@ func NewConfigCmd(cf *genericclioptions.ConfigFlags, outWriter io.Writer) *cobra
 		Short: "View the configuration parameters used by starboard scanners",
 		RunE: func(cmd *cobra.Command, args []string) (err error) {
 			ctx := context.Background()
-			config, err := cf.ToRESTConfig()
+			kubernetesConfig, err := cf.ToRESTConfig()
 			if err != nil {
 				return
 			}
-			clientset, err := kubernetes.NewForConfig(config)
+			clientset, err := kubernetes.NewForConfig(kubernetesConfig)
 			if err != nil {
 				return
 			}
-			configMap, err := clientset.CoreV1().ConfigMaps(kube.NamespaceStarboard).Get(ctx, kube.NamespaceStarboard, metav1.GetOptions{})
+			config, err := starboard.NewConfigReader(clientset).Read(ctx)
 			if err != nil {
 				return
 			}
-			filteredValues, err := getFilteredValues(configMap, &localFlags)
+			filteredValues, err := getFilteredValues(config, &localFlags)
 			if err != nil {
 				return
 			}
@@ -50,8 +49,7 @@ func NewConfigCmd(cf *genericclioptions.ConfigFlags, outWriter io.Writer) *cobra
 	return cmd
 }
 
-func getFilteredValues(configMap *v1.ConfigMap, localFlags *LocalFlags) (string, error) {
-	data := configMap.Data
+func getFilteredValues(data starboard.ConfigData, localFlags *LocalFlags) (string, error) {
 	if localFlags.get != "" {
 		value := data[localFlags.get]
 		if value != "" {
@@ -81,4 +79,3 @@ func setLocalFlags(cmd *cobra.Command, localFlags *LocalFlags) {
 	cmd.Flags().BoolVar(&localFlags.nameOnly, "name-only", false, "List parameters by name only")
 	cmd.Flags().StringVar(&localFlags.get, "get", "", "Get configuration parameters for a specified key")
 }
-
diff --git a/pkg/cmd/find_vulnerabilities.go b/pkg/cmd/find_vulnerabilities.go
index 3b35e02..cb13670 100644
--- a/pkg/cmd/find_vulnerabilities.go
+++ b/pkg/cmd/find_vulnerabilities.go
@@ -4,9 +4,11 @@ import (
 	"context"
 	"fmt"
 
+	starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/aquasecurity/starboard/pkg/find/vulnerabilities/crd"
 	"github.com/aquasecurity/starboard/pkg/find/vulnerabilities/trivy"
-	starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
 	"github.com/spf13/cobra"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/kubernetes"
@@ -62,23 +64,27 @@ NAME is the name of a particular Kubernetes workload.
 			if err != nil {
 				return
 			}
-			config, err := cf.ToRESTConfig()
+			kubernetesConfig, err := cf.ToRESTConfig()
 			if err != nil {
 				return
 			}
-			kubernetesClientset, err := kubernetes.NewForConfig(config)
+			kubernetesClientset, err := kubernetes.NewForConfig(kubernetesConfig)
 			if err != nil {
 				return err
 			}
+			config, err := starboard.NewConfigReader(kubernetesClientset).Read(ctx)
+			if err != nil {
+				return
+			}
 			opts, err := getScannerOpts(cmd)
 			if err != nil {
 				return
 			}
-			reports, owner, err := trivy.NewScanner(opts, kubernetesClientset).Scan(ctx, workload)
+			reports, owner, err := trivy.NewScanner(config, opts, kubernetesClientset).Scan(ctx, workload)
 			if err != nil {
 				return
 			}
-			starboardClientset, err := starboardapi.NewForConfig(config)
+			starboardClientset, err := starboardapi.NewForConfig(kubernetesConfig)
 			if err != nil {
 				return
 			}
diff --git a/pkg/cmd/kube_bench.go b/pkg/cmd/kube_bench.go
index 559c924..f6c05c2 100644
--- a/pkg/cmd/kube_bench.go
+++ b/pkg/cmd/kube_bench.go
@@ -5,13 +5,15 @@ import (
 	"fmt"
 	"sync"
 
-	core "k8s.io/api/core/v1"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 
-	starboard "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
+	corev1 "k8s.io/api/core/v1"
+
+	starboardapi "github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
 	"github.com/aquasecurity/starboard/pkg/kubebench"
 	"github.com/aquasecurity/starboard/pkg/kubebench/crd"
 	"github.com/spf13/cobra"
-	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/klog"
@@ -23,11 +25,11 @@ func NewKubeBenchCmd(cf *genericclioptions.ConfigFlags) *cobra.Command {
 		Short: "Run the CIS Kubernetes Benchmark https://www.cisecurity.org/benchmark/kubernetes",
 		RunE: func(cmd *cobra.Command, args []string) (err error) {
 			ctx := context.Background()
-			config, err := cf.ToRESTConfig()
+			kubernetesConfig, err := cf.ToRESTConfig()
 			if err != nil {
 				return
 			}
-			kubernetesClientset, err := kubernetes.NewForConfig(config)
+			kubernetesClientset, err := kubernetes.NewForConfig(kubernetesConfig)
 			if err != nil {
 				return
 			}
@@ -35,23 +37,28 @@ func NewKubeBenchCmd(cf *genericclioptions.ConfigFlags) *cobra.Command {
 			if err != nil {
 				return
 			}
-			starboardClientset, err := starboard.NewForConfig(config)
+			starboardClientset, err := starboardapi.NewForConfig(kubernetesConfig)
 			if err != nil {
 				return
 			}
-			nodeList, err := kubernetesClientset.CoreV1().Nodes().List(ctx, meta.ListOptions{})
+			nodeList, err := kubernetesClientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 			if err != nil {
 				err = fmt.Errorf("listing nodes: %w", err)
 				return
 			}
-			scanner := kubebench.NewScanner(opts, kubernetesClientset)
+			config, err := starboard.NewConfigReader(kubernetesClientset).Read(ctx)
+			if err != nil {
+				return err
+			}
+
+			scanner := kubebench.NewScanner(config, opts, kubernetesClientset)
 			writer := crd.NewReadWriter(GetScheme(), starboardClientset)
 
 			var wg sync.WaitGroup
 
 			for _, node := range nodeList.Items {
 				wg.Add(1)
-				go func(node core.Node) {
+				go func(node corev1.Node) {
 					defer wg.Done()
 
 					report, err := scanner.Scan(ctx, node)
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index 343748b..a599093 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -6,13 +6,15 @@ import (
 	"path/filepath"
 	"strings"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/spf13/pflag"
 
 	"github.com/spf13/cobra"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 )
 
-func NewRootCmd(version VersionInfo, args []string, outWriter io.Writer, errWriter io.Writer) *cobra.Command {
+func NewRootCmd(version starboard.BuildInfo, args []string, outWriter io.Writer, errWriter io.Writer) *cobra.Command {
 	var cf *genericclioptions.ConfigFlags
 
 	rootCmd := &cobra.Command{
@@ -54,7 +56,7 @@ func executable(args []string) string {
 
 // Run is the entry point of the Starboard CLI. It runs the specified
 // command based on the specified args.
-func Run(version VersionInfo, args []string, outWriter io.Writer, errWriter io.Writer) error {
+func Run(version starboard.BuildInfo, args []string, outWriter io.Writer, errWriter io.Writer) error {
 
 	initFlags()
 
diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go
index 4a3505d..9a8456a 100644
--- a/pkg/cmd/version.go
+++ b/pkg/cmd/version.go
@@ -4,16 +4,12 @@ import (
 	"fmt"
 	"io"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/spf13/cobra"
 )
 
-type VersionInfo struct {
-	Version string
-	Commit  string
-	Date    string
-}
-
-func NewVersionCmd(version VersionInfo, outWriter io.Writer) *cobra.Command {
+func NewVersionCmd(version starboard.BuildInfo, outWriter io.Writer) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "version",
 		Short: "Print the version information",
diff --git a/pkg/find/vulnerabilities/trivy/converter.go b/pkg/find/vulnerabilities/trivy/converter.go
index 6d4c490..48b395c 100644
--- a/pkg/find/vulnerabilities/trivy/converter.go
+++ b/pkg/find/vulnerabilities/trivy/converter.go
@@ -6,7 +6,9 @@ import (
 	"io/ioutil"
 	"strings"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/google/go-containerregistry/pkg/name"
 )
 
@@ -15,7 +17,7 @@ import (
 // Convert converts the vulnerabilities model used by Trivy
 // to a generic model defined by the Custom Security Resource Specification.
 type Converter interface {
-	Convert(imageRef string, reader io.Reader) (starboard.VulnerabilityScanResult, error)
+	Convert(config Config, imageRef string, reader io.Reader) (starboardv1alpha1.VulnerabilityScanResult, error)
 }
 
 type converter struct {
@@ -27,7 +29,7 @@ func NewConverter() Converter {
 	return &converter{}
 }
 
-func (c *converter) Convert(imageRef string, reader io.Reader) (report starboard.VulnerabilityScanResult, err error) {
+func (c *converter) Convert(config Config, imageRef string, reader io.Reader) (report starboardv1alpha1.VulnerabilityScanResult, err error) {
 	var scanReports []ScanReport
 	skipReader, err := c.skippingNoisyOutputReader(reader)
 	if err != nil {
@@ -37,7 +39,7 @@ func (c *converter) Convert(imageRef string, reader io.Reader) (report starboard
 	if err != nil {
 		return
 	}
-	return c.convert(imageRef, scanReports)
+	return c.convert(config, imageRef, scanReports)
 }
 
 // TODO Normally I'd use Trivy with the --quiet flag, but in case of errors it does suppress the error message.
@@ -60,12 +62,12 @@ func (c *converter) skippingNoisyOutputReader(input io.Reader) (io.Reader, error
 	return strings.NewReader(inputAsString), nil
 }
 
-func (c *converter) convert(imageRef string, reports []ScanReport) (starboard.VulnerabilityScanResult, error) {
-	vulnerabilities := make([]starboard.Vulnerability, 0)
+func (c *converter) convert(config Config, imageRef string, reports []ScanReport) (starboardv1alpha1.VulnerabilityScanResult, error) {
+	vulnerabilities := make([]starboardv1alpha1.Vulnerability, 0)
 
 	for _, report := range reports {
 		for _, sr := range report.Vulnerabilities {
-			vulnerabilities = append(vulnerabilities, starboard.Vulnerability{
+			vulnerabilities = append(vulnerabilities, starboardv1alpha1.Vulnerability{
 				VulnerabilityID:  sr.VulnerabilityID,
 				Resource:         sr.PkgName,
 				InstalledVersion: sr.InstalledVersion,
@@ -80,14 +82,19 @@ func (c *converter) convert(imageRef string, reports []ScanReport) (starboard.Vu
 
 	registry, artifact, err := c.parseImageRef(imageRef)
 	if err != nil {
-		return starboard.VulnerabilityScanResult{}, err
+		return starboardv1alpha1.VulnerabilityScanResult{}, err
+	}
+
+	version, err := starboard.GetVersionFromImageRef(config.GetTrivyImageRef())
+	if err != nil {
+		return starboardv1alpha1.VulnerabilityScanResult{}, err
 	}
 
-	return starboard.VulnerabilityScanResult{
-		Scanner: starboard.Scanner{
+	return starboardv1alpha1.VulnerabilityScanResult{
+		Scanner: starboardv1alpha1.Scanner{
 			Name:    "Trivy",
 			Vendor:  "Aqua Security",
-			Version: trivyVersion,
+			Version: version,
 		},
 		Registry:        registry,
 		Artifact:        artifact,
@@ -103,16 +110,16 @@ func (c *converter) toLinks(references []string) []string {
 	return references
 }
 
-func (c *converter) toSummary(vulnerabilities []starboard.Vulnerability) (vs starboard.VulnerabilitySummary) {
+func (c *converter) toSummary(vulnerabilities []starboardv1alpha1.Vulnerability) (vs starboardv1alpha1.VulnerabilitySummary) {
 	for _, v := range vulnerabilities {
 		switch v.Severity {
-		case starboard.SeverityCritical:
+		case starboardv1alpha1.SeverityCritical:
 			vs.CriticalCount++
-		case starboard.SeverityHigh:
+		case starboardv1alpha1.SeverityHigh:
 			vs.HighCount++
-		case starboard.SeverityMedium:
+		case starboardv1alpha1.SeverityMedium:
 			vs.MediumCount++
-		case starboard.SeverityLow:
+		case starboardv1alpha1.SeverityLow:
 			vs.LowCount++
 		default:
 			vs.UnknownCount++
@@ -121,15 +128,15 @@ func (c *converter) toSummary(vulnerabilities []starboard.Vulnerability) (vs sta
 	return
 }
 
-func (c *converter) parseImageRef(imageRef string) (starboard.Registry, starboard.Artifact, error) {
+func (c *converter) parseImageRef(imageRef string) (starboardv1alpha1.Registry, starboardv1alpha1.Artifact, error) {
 	ref, err := name.ParseReference(imageRef)
 	if err != nil {
-		return starboard.Registry{}, starboard.Artifact{}, err
+		return starboardv1alpha1.Registry{}, starboardv1alpha1.Artifact{}, err
 	}
-	registry := starboard.Registry{
+	registry := starboardv1alpha1.Registry{
 		Server: ref.Context().RegistryStr(),
 	}
-	artifact := starboard.Artifact{
+	artifact := starboardv1alpha1.Artifact{
 		Repository: ref.Context().RepositoryStr(),
 	}
 	switch t := ref.(type) {
diff --git a/pkg/find/vulnerabilities/trivy/scanner.go b/pkg/find/vulnerabilities/trivy/scanner.go
index efd8b1b..823adab 100644
--- a/pkg/find/vulnerabilities/trivy/scanner.go
+++ b/pkg/find/vulnerabilities/trivy/scanner.go
@@ -3,12 +3,11 @@ package trivy
 import (
 	"context"
 	"fmt"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 	"io"
 
 	"github.com/aquasecurity/starboard/pkg/docker"
 	"github.com/aquasecurity/starboard/pkg/kube/secrets"
-	"k8s.io/apimachinery/pkg/api/errors"
-
 	"github.com/aquasecurity/starboard/pkg/scanners"
 	"k8s.io/klog"
 
@@ -27,17 +26,14 @@ import (
 	"k8s.io/utils/pointer"
 )
 
-const (
-	trivyVersion = "0.9.1"
-)
-
-var (
-	trivyImageRef = fmt.Sprintf("docker.io/aquasec/trivy:%s", trivyVersion)
-)
+type Config interface {
+	GetTrivyImageRef() string
+}
 
 // NewScanner constructs a new vulnerability Scanner with the specified options and Kubernetes client Interface.
-func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner {
+func NewScanner(config Config, opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner {
 	return &Scanner{
+		config:    config,
 		opts:      opts,
 		clientset: clientset,
 		pods:      pod.NewPodManager(clientset),
@@ -46,6 +42,7 @@ func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner
 }
 
 type Scanner struct {
+	config    Config
 	opts      kube.ScannerOpts
 	clientset kubernetes.Interface
 	pods      *pod.Manager
@@ -86,8 +83,8 @@ func (s *Scanner) ScanByPodSpec(ctx context.Context, workload kube.Object, spec
 	}
 
 	if imagePullSecret != nil {
-		klog.V(3).Infof("Creating image pull secret: %s/%s", kube.NamespaceStarboard, imagePullSecret.Name)
-		_, err = s.clientset.CoreV1().Secrets(kube.NamespaceStarboard).Create(ctx, imagePullSecret, meta.CreateOptions{})
+		klog.V(3).Infof("Creating image pull secret: %s/%s", starboard.NamespaceName, imagePullSecret.Name)
+		_, err = s.clientset.CoreV1().Secrets(starboard.NamespaceName).Create(ctx, imagePullSecret, meta.CreateOptions{})
 		if err != nil {
 			return nil, err
 		}
@@ -133,15 +130,11 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 	imagePullSecretName := jobName
 	imagePullSecretData := make(map[string][]byte)
 	var imagePullSecret *core.Secret
-	trivyImage, err := s.getTrivyImageRef()
-	if err != nil {
-		return nil, nil, err
-	}
 
 	initContainers := []core.Container{
 		{
 			Name:                     initContainerName,
-			Image:                    trivyImage,
+			Image:                    s.config.GetTrivyImageRef(),
 			ImagePullPolicy:          core.PullIfNotPresent,
 			TerminationMessagePolicy: core.TerminationMessageFallbackToLogsOnError,
 			Env: []core.EnvVar{
@@ -150,7 +143,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 					ValueFrom: &core.EnvVarSource{
 						ConfigMapKeyRef: &core.ConfigMapKeySelector{
 							LocalObjectReference: core.LocalObjectReference{
-								Name: kube.ConfigMapStarboard,
+								Name: starboard.ConfigMapName,
 							},
 							Key:      "trivy.httpProxy",
 							Optional: pointer.BoolPtr(true),
@@ -162,7 +155,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 					ValueFrom: &core.EnvVarSource{
 						ConfigMapKeyRef: &core.ConfigMapKeySelector{
 							LocalObjectReference: core.LocalObjectReference{
-								Name: kube.ConfigMapStarboard,
+								Name: starboard.ConfigMapName,
 							},
 							Key:      "trivy.githubToken",
 							Optional: pointer.BoolPtr(true),
@@ -202,7 +195,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 				ValueFrom: &core.EnvVarSource{
 					ConfigMapKeyRef: &core.ConfigMapKeySelector{
 						LocalObjectReference: core.LocalObjectReference{
-							Name: kube.ConfigMapStarboard,
+							Name: starboard.ConfigMapName,
 						},
 						Key:      "trivy.severity",
 						Optional: pointer.BoolPtr(true),
@@ -213,7 +206,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 				ValueFrom: &core.EnvVarSource{
 					ConfigMapKeyRef: &core.ConfigMapKeySelector{
 						LocalObjectReference: core.LocalObjectReference{
-							Name: kube.ConfigMapStarboard,
+							Name: starboard.ConfigMapName,
 						},
 						Key:      "trivy.httpProxy",
 						Optional: pointer.BoolPtr(true),
@@ -254,7 +247,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 
 		scanJobContainers[i] = core.Container{
 			Name:                     c.Name,
-			Image:                    trivyImage,
+			Image:                    s.config.GetTrivyImageRef(),
 			ImagePullPolicy:          core.PullIfNotPresent,
 			TerminationMessagePolicy: core.TerminationMessageFallbackToLogsOnError,
 			Env:                      envs,
@@ -299,7 +292,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 		imagePullSecret = &core.Secret{
 			ObjectMeta: meta.ObjectMeta{
 				Name:      imagePullSecretName,
-				Namespace: kube.NamespaceStarboard,
+				Namespace: starboard.NamespaceName,
 				Labels: map[string]string{
 					kube.LabelResourceKind:      string(workload.Kind),
 					kube.LabelResourceName:      workload.Name,
@@ -313,7 +306,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 	return &batch.Job{
 		ObjectMeta: meta.ObjectMeta{
 			Name:      jobName,
-			Namespace: kube.NamespaceStarboard,
+			Namespace: starboard.NamespaceName,
 			Labels: map[string]string{
 				kube.LabelResourceKind:      string(workload.Kind),
 				kube.LabelResourceName:      workload.Name,
@@ -336,7 +329,7 @@ func (s *Scanner) PrepareScanJob(_ context.Context, workload kube.Object, spec c
 					},
 				},
 				Spec: core.PodSpec{
-					ServiceAccountName: kube.ServiceAccountStarboard,
+					ServiceAccountName: starboard.ServiceAccountName,
 					Volumes: []core.Volume{
 						{
 							Name: "data",
@@ -381,7 +374,7 @@ func (s *Scanner) GetVulnerabilityReportsByScanJob(ctx context.Context, job *bat
 		if err != nil {
 			return
 		}
-		reports[c.Name], err = s.converter.Convert(containerImages[c.Name], logReader)
+		reports[c.Name], err = s.converter.Convert(s.config, containerImages[c.Name], logReader)
 		_ = logReader.Close()
 		if err != nil {
 			return
@@ -389,18 +382,3 @@ func (s *Scanner) GetVulnerabilityReportsByScanJob(ctx context.Context, job *bat
 	}
 	return
 }
-
-func (s *Scanner) getTrivyImageRef() (string, error) {
-	cm, err := s.clientset.CoreV1().ConfigMaps(kube.NamespaceStarboard).Get(context.Background(), kube.ConfigMapStarboard, meta.GetOptions{})
-	if err != nil && errors.IsNotFound(err) {
-		return trivyImageRef, nil
-	}
-	if err != nil {
-		return "", err
-	}
-	imageRef := cm.Data["trivy.imageRef"]
-	if imageRef != "" {
-		return imageRef, nil
-	}
-	return trivyImageRef, nil
-}
diff --git a/pkg/kube/cr_manager.go b/pkg/kube/cr_manager.go
index 5117374..8a66f78 100644
--- a/pkg/kube/cr_manager.go
+++ b/pkg/kube/cr_manager.go
@@ -3,13 +3,14 @@ package kube
 import (
 	"context"
 	"fmt"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 	"time"
 
 	"k8s.io/utils/pointer"
 
 	"k8s.io/apimachinery/pkg/labels"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	aquasecurityv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	core "k8s.io/api/core/v1"
 	rbac "k8s.io/api/rbac/v1"
 	ext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@@ -25,197 +26,10 @@ const (
 	clusterRoleBindingStarboard = "starboard"
 )
 
-const (
-	polarisConfigYAML = `checks:
-  # reliability
-  multipleReplicasForDeployment: ignore
-  priorityClassNotSet: ignore
-  # resources
-  cpuRequestsMissing: warning
-  cpuLimitsMissing: warning
-  memoryRequestsMissing: warning
-  memoryLimitsMissing: warning
-  # images
-  tagNotSpecified: danger
-  pullPolicyNotAlways: ignore
-  # healthChecks
-  readinessProbeMissing: warning
-  livenessProbeMissing: warning
-  # networking
-  hostNetworkSet: warning
-  hostPortSet: warning
-  # security
-  hostIPCSet: danger
-  hostPIDSet: danger
-  notReadOnlyRootFilesystem: warning
-  privilegeEscalationAllowed: danger
-  runAsRootAllowed: warning
-  runAsPrivileged: danger
-  dangerousCapabilities: danger
-  insecureCapabilities: warning
-exemptions:
-  - controllerNames:
-    - kube-apiserver
-    - kube-proxy
-    - kube-scheduler
-    - etcd-manager-events
-    - kube-controller-manager
-    - kube-dns
-    - etcd-manager-main
-    rules:
-    - hostPortSet
-    - hostNetworkSet
-    - readinessProbeMissing
-    - livenessProbeMissing
-    - cpuRequestsMissing
-    - cpuLimitsMissing
-    - memoryRequestsMissing
-    - memoryLimitsMissing
-    - runAsRootAllowed
-    - runAsPrivileged
-    - notReadOnlyRootFilesystem
-    - hostPIDSet
-  - controllerNames:
-    - kube-flannel-ds
-    rules:
-    - notReadOnlyRootFilesystem
-    - runAsRootAllowed
-    - notReadOnlyRootFilesystem
-    - readinessProbeMissing
-    - livenessProbeMissing
-    - cpuLimitsMissing
-  - controllerNames:
-    - cert-manager
-    rules:
-    - notReadOnlyRootFilesystem
-    - runAsRootAllowed
-    - readinessProbeMissing
-    - livenessProbeMissing
-  - controllerNames:
-    - cluster-autoscaler
-    rules:
-    - notReadOnlyRootFilesystem
-    - runAsRootAllowed
-    - readinessProbeMissing
-  - controllerNames:
-    - vpa
-    rules:
-    - runAsRootAllowed
-    - readinessProbeMissing
-    - livenessProbeMissing
-    - notReadOnlyRootFilesystem
-  - controllerNames:
-    - datadog
-    rules:
-    - runAsRootAllowed
-    - readinessProbeMissing
-    - livenessProbeMissing
-    - notReadOnlyRootFilesystem
-  - controllerNames:
-    - nginx-ingress-controller
-    rules:
-    - privilegeEscalationAllowed
-    - insecureCapabilities
-    - runAsRootAllowed
-  - controllerNames:
-    - dns-controller
-    - datadog-datadog
-    - kube-flannel-ds
-    - kube2iam
-    - aws-iam-authenticator
-    - datadog
-    - kube2iam
-    rules:
-    - hostNetworkSet
-  - controllerNames:
-    - aws-iam-authenticator
-    - aws-cluster-autoscaler
-    - kube-state-metrics
-    - dns-controller
-    - external-dns
-    - dnsmasq
-    - autoscaler
-    - kubernetes-dashboard
-    - install-cni
-    - kube2iam
-    rules:
-    - readinessProbeMissing
-    - livenessProbeMissing
-  - controllerNames:
-    - aws-iam-authenticator
-    - nginx-ingress-default-backend
-    - aws-cluster-autoscaler
-    - kube-state-metrics
-    - dns-controller
-    - external-dns
-    - kubedns
-    - dnsmasq
-    - autoscaler
-    - tiller
-    - kube2iam
-    rules:
-    - runAsRootAllowed
-  - controllerNames:
-    - aws-iam-authenticator
-    - nginx-ingress-controller
-    - nginx-ingress-default-backend
-    - aws-cluster-autoscaler
-    - kube-state-metrics
-    - dns-controller
-    - external-dns
-    - kubedns
-    - dnsmasq
-    - autoscaler
-    - tiller
-    - kube2iam
-    rules:
-    - notReadOnlyRootFilesystem
-  - controllerNames:
-    - cert-manager
-    - dns-controller
-    - kubedns
-    - dnsmasq
-    - autoscaler
-    - insights-agent-goldilocks-vpa-install
-    - datadog
-    rules:
-    - cpuRequestsMissing
-    - cpuLimitsMissing
-    - memoryRequestsMissing
-    - memoryLimitsMissing
-  - controllerNames:
-    - kube2iam
-    - kube-flannel-ds
-    rules:
-    - runAsPrivileged
-  - controllerNames:
-    - kube-hunter
-    rules:
-    - hostPIDSet
-  - controllerNames:
-    - polaris
-    - kube-hunter
-    - goldilocks
-    - insights-agent-goldilocks-vpa-install
-    rules:
-    - notReadOnlyRootFilesystem
-  - controllerNames:
-    - insights-agent-goldilocks-controller
-    rules:
-    - livenessProbeMissing
-    - readinessProbeMissing
-  - controllerNames:
-    - insights-agent-goldilocks-vpa-install
-    - kube-hunter
-    rules:
-    - runAsRootAllowed
-`
-)
-
 var (
 	namespace = &core.Namespace{
 		ObjectMeta: meta.ObjectMeta{
-			Name: NamespaceStarboard,
+			Name: starboard.NamespaceName,
 			Labels: labels.Set{
 				"app.kubernetes.io/managed-by": "starboard",
 			},
@@ -223,7 +37,7 @@ var (
 	}
 	serviceAccount = &core.ServiceAccount{
 		ObjectMeta: meta.ObjectMeta{
-			Name: ServiceAccountStarboard,
+			Name: starboard.ServiceAccountName,
 			Labels: labels.Set{
 				"app.kubernetes.io/managed-by": "starboard",
 			},
@@ -232,16 +46,12 @@ var (
 	}
 	configMap = &core.ConfigMap{
 		ObjectMeta: meta.ObjectMeta{
-			Name: ConfigMapStarboard,
+			Name: starboard.ConfigMapName,
 			Labels: labels.Set{
 				"app.kubernetes.io/managed-by": "starboard",
 			},
 		},
-		Data: map[string]string{
-			"trivy.severity":      "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL",
-			"trivy.imageRef":      "docker.io/aquasec/trivy:0.9.1",
-			"polaris.config.yaml": polarisConfigYAML,
-		},
+		Data: starboard.GetDefaultConfig(),
 	}
 	clusterRole = &rbac.ClusterRole{
 		ObjectMeta: meta.ObjectMeta{
@@ -311,8 +121,8 @@ var (
 		Subjects: []rbac.Subject{
 			{
 				Kind:      "ServiceAccount",
-				Name:      ServiceAccountStarboard,
-				Namespace: NamespaceStarboard,
+				Name:      starboard.ServiceAccountName,
+				Namespace: starboard.NamespaceName,
 			},
 		},
 	}
@@ -339,22 +149,22 @@ func NewCRManager(clientset kubernetes.Interface, clientsetext extapi.Apiextensi
 }
 
 func (m *crManager) Init(ctx context.Context) (err error) {
-	err = m.createOrUpdateCRD(ctx, &starboard.VulnerabilityReportsCRD)
+	err = m.createOrUpdateCRD(ctx, &aquasecurityv1alpha1.VulnerabilityReportsCRD)
 	if err != nil {
 		return
 	}
 
-	err = m.createOrUpdateCRD(ctx, &starboard.CISKubeBenchReportCRD)
+	err = m.createOrUpdateCRD(ctx, &aquasecurityv1alpha1.CISKubeBenchReportCRD)
 	if err != nil {
 		return
 	}
 
-	err = m.createOrUpdateCRD(ctx, &starboard.KubeHunterReportCRD)
+	err = m.createOrUpdateCRD(ctx, &aquasecurityv1alpha1.KubeHunterReportCRD)
 	if err != nil {
 		return
 	}
 
-	err = m.createOrUpdateCRD(ctx, &starboard.ConfigAuditReportCRD)
+	err = m.createOrUpdateCRD(ctx, &aquasecurityv1alpha1.ConfigAuditReportCRD)
 	if err != nil {
 		return
 	}
@@ -401,8 +211,8 @@ func (m *crManager) cleanupRBAC(ctx context.Context) (err error) {
 	if err != nil && !errors.IsNotFound(err) {
 		return
 	}
-	klog.V(3).Infof("Deleting ServiceAccount %q", NamespaceStarboard+"/"+ServiceAccountStarboard)
-	err = m.clientset.CoreV1().ServiceAccounts(NamespaceStarboard).Delete(ctx, ServiceAccountStarboard, meta.DeleteOptions{})
+	klog.V(3).Infof("Deleting ServiceAccount %q", starboard.NamespaceName+"/"+starboard.ServiceAccountName)
+	err = m.clientset.CoreV1().ServiceAccounts(starboard.NamespaceName).Delete(ctx, starboard.ServiceAccountName, meta.DeleteOptions{})
 	if err != nil && !errors.IsNotFound(err) {
 		return
 	}
@@ -415,8 +225,8 @@ var (
 )
 
 func (m *crManager) cleanupNamespace(ctx context.Context) error {
-	klog.V(3).Infof("Deleting Namespace %q", NamespaceStarboard)
-	err := m.clientset.CoreV1().Namespaces().Delete(ctx, NamespaceStarboard, meta.DeleteOptions{})
+	klog.V(3).Infof("Deleting Namespace %q", starboard.NamespaceName)
+	err := m.clientset.CoreV1().Namespaces().Delete(ctx, starboard.NamespaceName, meta.DeleteOptions{})
 	if err != nil && !errors.IsNotFound(err) {
 		return err
 	}
@@ -424,9 +234,9 @@ func (m *crManager) cleanupNamespace(ctx context.Context) error {
 		select {
 		// This case controls the polling interval
 		case <-time.After(cleanupPollingInterval):
-			_, err := m.clientset.CoreV1().Namespaces().Get(ctx, NamespaceStarboard, meta.GetOptions{})
+			_, err := m.clientset.CoreV1().Namespaces().Get(ctx, starboard.NamespaceName, meta.GetOptions{})
 			if errors.IsNotFound(err) {
-				klog.V(3).Infof("Deleted Namespace %q", NamespaceStarboard)
+				klog.V(3).Infof("Deleted Namespace %q", starboard.NamespaceName)
 				return nil
 			}
 		// This case caters for polling timeout
@@ -452,14 +262,14 @@ func (m *crManager) createNamespaceIfNotFound(ctx context.Context, ns *core.Name
 
 func (m *crManager) createServiceAccountIfNotFound(ctx context.Context, sa *core.ServiceAccount) (err error) {
 	name := sa.Name
-	_, err = m.clientset.CoreV1().ServiceAccounts(NamespaceStarboard).Get(ctx, name, meta.GetOptions{})
+	_, err = m.clientset.CoreV1().ServiceAccounts(starboard.NamespaceName).Get(ctx, name, meta.GetOptions{})
 	switch {
 	case err == nil:
-		klog.V(3).Infof("ServiceAccount %q already exists", NamespaceStarboard+"/"+name)
+		klog.V(3).Infof("ServiceAccount %q already exists", starboard.NamespaceName+"/"+name)
 		return
 	case errors.IsNotFound(err):
-		klog.V(3).Infof("Creating ServiceAccount %q", NamespaceStarboard+"/"+name)
-		_, err = m.clientset.CoreV1().ServiceAccounts(NamespaceStarboard).Create(ctx, sa, meta.CreateOptions{})
+		klog.V(3).Infof("Creating ServiceAccount %q", starboard.NamespaceName+"/"+name)
+		_, err = m.clientset.CoreV1().ServiceAccounts(starboard.NamespaceName).Create(ctx, sa, meta.CreateOptions{})
 		return
 	}
 	return
@@ -467,14 +277,14 @@ func (m *crManager) createServiceAccountIfNotFound(ctx context.Context, sa *core
 
 func (m *crManager) createConfigMapIfNotFound(ctx context.Context, cm *core.ConfigMap) (err error) {
 	name := cm.Name
-	_, err = m.clientset.CoreV1().ConfigMaps(NamespaceStarboard).Get(ctx, name, meta.GetOptions{})
+	_, err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Get(ctx, name, meta.GetOptions{})
 	switch {
 	case err == nil:
-		klog.V(3).Infof("ConfigMap %q already exists", NamespaceStarboard+"/"+name)
+		klog.V(3).Infof("ConfigMap %q already exists", starboard.NamespaceName+"/"+name)
 		return
 	case errors.IsNotFound(err):
-		klog.V(3).Infof("Creating ConfigMap %q", NamespaceStarboard+"/"+name)
-		_, err = m.clientset.CoreV1().ConfigMaps(NamespaceStarboard).Create(ctx, cm, meta.CreateOptions{})
+		klog.V(3).Infof("Creating ConfigMap %q", starboard.NamespaceName+"/"+name)
+		_, err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Create(ctx, cm, meta.CreateOptions{})
 		return
 	}
 	return
@@ -543,19 +353,19 @@ func (m *crManager) deleteCRD(ctx context.Context, name string) (err error) {
 }
 
 func (m *crManager) Cleanup(ctx context.Context) (err error) {
-	err = m.deleteCRD(ctx, starboard.VulnerabilityReportsCRName)
+	err = m.deleteCRD(ctx, aquasecurityv1alpha1.VulnerabilityReportsCRName)
 	if err != nil {
 		return
 	}
-	err = m.deleteCRD(ctx, starboard.CISKubeBenchReportCRName)
+	err = m.deleteCRD(ctx, aquasecurityv1alpha1.CISKubeBenchReportCRName)
 	if err != nil {
 		return
 	}
-	err = m.deleteCRD(ctx, starboard.KubeHunterReportCRName)
+	err = m.deleteCRD(ctx, aquasecurityv1alpha1.KubeHunterReportCRName)
 	if err != nil {
 		return
 	}
-	err = m.deleteCRD(ctx, starboard.ConfigAuditReportCRName)
+	err = m.deleteCRD(ctx, aquasecurityv1alpha1.ConfigAuditReportCRName)
 	if err != nil {
 		return
 	}
@@ -564,8 +374,8 @@ func (m *crManager) Cleanup(ctx context.Context) (err error) {
 		return
 	}
 
-	klog.V(3).Infof("Deleting ConfigMap %q", NamespaceStarboard+"/"+ConfigMapStarboard)
-	err = m.clientset.CoreV1().ConfigMaps(NamespaceStarboard).Delete(ctx, ConfigMapStarboard, meta.DeleteOptions{})
+	klog.V(3).Infof("Deleting ConfigMap %q", starboard.NamespaceName+"/"+starboard.ConfigMapName)
+	err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Delete(ctx, starboard.ConfigMapName, meta.DeleteOptions{})
 	if err != nil && !errors.IsNotFound(err) {
 		return
 	}
diff --git a/pkg/kube/starboard.go b/pkg/kube/starboard.go
index 3782085..8cb4e10 100644
--- a/pkg/kube/starboard.go
+++ b/pkg/kube/starboard.go
@@ -4,17 +4,6 @@ import (
 	"time"
 )
 
-const (
-	// NamespaceStarboard the name of the namespace in which Starboard stores its
-	// configuration and runs scan Jobs.
-	NamespaceStarboard = "starboard"
-	// ServiceAccountStarboard the name of the ServiceAccount used to run scan Jobs.
-	ServiceAccountStarboard = "starboard"
-	// ConfigMapStarboard the name of the ConfigMap that stored configuration of
-	// Starboard and the underlying scanners.
-	ConfigMapStarboard = "starboard"
-)
-
 const (
 	// TODO I'm wondering if we should rename starboard.resource.* labels to starboard.object.*
 	// TODO In Kubernetes API terminology a resource is usually lowercase, plural word (e.g. pods) identifying a set of
diff --git a/pkg/kubebench/converter.go b/pkg/kubebench/converter.go
index 7b36459..8d50739 100644
--- a/pkg/kubebench/converter.go
+++ b/pkg/kubebench/converter.go
@@ -4,11 +4,13 @@ import (
 	"encoding/json"
 	"io"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
+	aquasecurityv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 )
 
 type Converter interface {
-	Convert(reader io.Reader) (report starboard.CISKubeBenchOutput, err error)
+	Convert(config Config, reader io.Reader) (aquasecurityv1alpha1.CISKubeBenchOutput, error)
 }
 
 var DefaultConverter Converter = &converter{}
@@ -16,19 +18,24 @@ var DefaultConverter Converter = &converter{}
 type converter struct {
 }
 
-func (c *converter) Convert(reader io.Reader) (report starboard.CISKubeBenchOutput, err error) {
+func (c *converter) Convert(config Config, reader io.Reader) (report aquasecurityv1alpha1.CISKubeBenchOutput, err error) {
 	decoder := json.NewDecoder(reader)
-	var section []starboard.CISKubeBenchSection
+	var section []aquasecurityv1alpha1.CISKubeBenchSection
 	err = decoder.Decode(&section)
 	if err != nil {
 		return
 	}
 
-	report = starboard.CISKubeBenchOutput{
-		Scanner: starboard.Scanner{
+	version, err := starboard.GetVersionFromImageRef(config.GetKubeBenchImageRef())
+	if err != nil {
+		return aquasecurityv1alpha1.CISKubeBenchOutput{}, err
+	}
+
+	report = aquasecurityv1alpha1.CISKubeBenchOutput{
+		Scanner: aquasecurityv1alpha1.Scanner{
 			Name:    "kube-bench",
 			Vendor:  "Aqua Security",
-			Version: kubeBenchVersion,
+			Version: version,
 		},
 		Summary:  c.summary(section),
 		Sections: section,
@@ -37,7 +44,7 @@ func (c *converter) Convert(reader io.Reader) (report starboard.CISKubeBenchOutp
 	return
 }
 
-func (c *converter) summary(sections []starboard.CISKubeBenchSection) starboard.CISKubeBenchSummary {
+func (c *converter) summary(sections []aquasecurityv1alpha1.CISKubeBenchSection) aquasecurityv1alpha1.CISKubeBenchSummary {
 	totalPass := 0
 	totalInfo := 0
 	totalWarn := 0
@@ -50,7 +57,7 @@ func (c *converter) summary(sections []starboard.CISKubeBenchSection) starboard.
 		totalFail += section.TotalFail
 	}
 
-	return starboard.CISKubeBenchSummary{
+	return aquasecurityv1alpha1.CISKubeBenchSummary{
 		PassCount: totalPass,
 		InfoCount: totalInfo,
 		WarnCount: totalWarn,
diff --git a/pkg/kubebench/scanner.go b/pkg/kubebench/scanner.go
index 602f85e..e6281d0 100644
--- a/pkg/kubebench/scanner.go
+++ b/pkg/kubebench/scanner.go
@@ -4,13 +4,15 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"k8s.io/apimachinery/pkg/labels"
 
 	"github.com/aquasecurity/starboard/pkg/scanners"
 
 	"k8s.io/klog"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 
 	"github.com/aquasecurity/starboard/pkg/kube"
 	"github.com/aquasecurity/starboard/pkg/kube/pod"
@@ -26,24 +28,25 @@ import (
 )
 
 const (
-	kubeBenchVersion       = "0.3.1"
 	kubeBenchContainerName = "kube-bench"
 	masterNodeLabel        = "node-role.kubernetes.io/master"
 )
 
-var (
-	kubeBenchContainerImage = fmt.Sprintf("aquasec/kube-bench:%s", kubeBenchVersion)
-)
+type Config interface {
+	GetKubeBenchImageRef() string
+}
 
 type Scanner struct {
+	config    Config
 	opts      kube.ScannerOpts
 	clientset kubernetes.Interface
 	pods      *pod.Manager
 	converter Converter
 }
 
-func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner {
+func NewScanner(config Config, opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner {
 	return &Scanner{
+		config:    config,
 		opts:      opts,
 		clientset: clientset,
 		pods:      pod.NewPodManager(clientset),
@@ -51,7 +54,7 @@ func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner
 	}
 }
 
-func (s *Scanner) Scan(ctx context.Context, node core.Node) (report starboard.CISKubeBenchOutput, err error) {
+func (s *Scanner) Scan(ctx context.Context, node core.Node) (report starboardv1alpha1.CISKubeBenchOutput, err error) {
 	// 1. Prepare descriptor for the Kubernetes Job which will run kube-bench
 	job := s.prepareKubeBenchJob(node)
 
@@ -95,7 +98,7 @@ func (s *Scanner) Scan(ctx context.Context, node core.Node) (report starboard.CI
 	}()
 
 	// 5. Parse the CISBenchmarkReport from the logs Reader
-	report, err = s.converter.Convert(logsReader)
+	report, err = s.converter.Convert(s.config, logsReader)
 	if err != nil {
 		err = fmt.Errorf("parsing CIS benchmark report: %w", err)
 		return
@@ -112,7 +115,7 @@ func (s *Scanner) prepareKubeBenchJob(node core.Node) *batch.Job {
 	return &batch.Job{
 		ObjectMeta: meta.ObjectMeta{
 			Name:      uuid.New().String(),
-			Namespace: kube.NamespaceStarboard,
+			Namespace: starboard.NamespaceName,
 			Labels: labels.Set{
 				"app.kubernetes.io/name": "starboard-cli",
 				kube.LabelResourceKind:   string(kube.KindNode),
@@ -132,7 +135,7 @@ func (s *Scanner) prepareKubeBenchJob(node core.Node) *batch.Job {
 					},
 				},
 				Spec: core.PodSpec{
-					ServiceAccountName:           kube.ServiceAccountStarboard,
+					ServiceAccountName:           starboard.ServiceAccountName,
 					AutomountServiceAccountToken: pointer.BoolPtr(true),
 					RestartPolicy:                core.RestartPolicyNever,
 					HostPID:                      true,
@@ -182,7 +185,7 @@ func (s *Scanner) prepareKubeBenchJob(node core.Node) *batch.Job {
 					Containers: []core.Container{
 						{
 							Name:                     kubeBenchContainerName,
-							Image:                    kubeBenchContainerImage,
+							Image:                    s.config.GetKubeBenchImageRef(),
 							ImagePullPolicy:          core.PullIfNotPresent,
 							TerminationMessagePolicy: core.TerminationMessageFallbackToLogsOnError,
 							Command:                  []string{"kube-bench", target},
diff --git a/pkg/kubehunter/scanner.go b/pkg/kubehunter/scanner.go
index 3092869..7a4f018 100644
--- a/pkg/kubehunter/scanner.go
+++ b/pkg/kubehunter/scanner.go
@@ -4,20 +4,22 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/aquasecurity/starboard/pkg/scanners"
 
 	"k8s.io/klog"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 
 	"github.com/aquasecurity/starboard/pkg/kube"
 	"github.com/aquasecurity/starboard/pkg/kube/pod"
 	"github.com/aquasecurity/starboard/pkg/runner"
 	"github.com/google/uuid"
-	batch "k8s.io/api/batch/v1"
-	core "k8s.io/api/core/v1"
+	batchv1 "k8s.io/api/batch/v1"
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
-	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/utils/pointer"
 )
@@ -45,7 +47,7 @@ func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner
 	}
 }
 
-func (s *Scanner) Scan(ctx context.Context) (report starboard.KubeHunterOutput, err error) {
+func (s *Scanner) Scan(ctx context.Context) (report starboardv1alpha1.KubeHunterOutput, err error) {
 	// 1. Prepare descriptor for the Kubernetes Job which will run kube-hunter
 	job := s.prepareKubeHunterJob()
 
@@ -63,8 +65,8 @@ func (s *Scanner) Scan(ctx context.Context) (report starboard.KubeHunterOutput,
 		}
 		// 5. Delete the kube-hunter Job
 		klog.V(3).Infof("Deleting job: %s/%s", job.Namespace, job.Name)
-		background := meta.DeletePropagationBackground
-		_ = s.clientset.BatchV1().Jobs(job.Namespace).Delete(ctx, job.Name, meta.DeleteOptions{
+		background := metav1.DeletePropagationBackground
+		_ = s.clientset.BatchV1().Jobs(job.Namespace).Delete(ctx, job.Name, metav1.DeleteOptions{
 			PropagationPolicy: &background,
 		})
 	}()
@@ -91,45 +93,45 @@ func (s *Scanner) Scan(ctx context.Context) (report starboard.KubeHunterOutput,
 	return
 }
 
-func (s *Scanner) prepareKubeHunterJob() *batch.Job {
-	return &batch.Job{
-		ObjectMeta: meta.ObjectMeta{
+func (s *Scanner) prepareKubeHunterJob() *batchv1.Job {
+	return &batchv1.Job{
+		ObjectMeta: metav1.ObjectMeta{
 			Name:      uuid.New().String(),
-			Namespace: kube.NamespaceStarboard,
+			Namespace: starboard.NamespaceName,
 			Labels: map[string]string{
 				"app": "kube-hunter",
 			},
 		},
-		Spec: batch.JobSpec{
+		Spec: batchv1.JobSpec{
 			BackoffLimit:          pointer.Int32Ptr(0),
 			Completions:           pointer.Int32Ptr(1),
 			ActiveDeadlineSeconds: scanners.GetActiveDeadlineSeconds(s.opts.ScanJobTimeout),
-			Template: core.PodTemplateSpec{
-				ObjectMeta: meta.ObjectMeta{
+			Template: corev1.PodTemplateSpec{
+				ObjectMeta: metav1.ObjectMeta{
 					Labels: map[string]string{
 						"app": "kube-hunter",
 					},
 				},
-				Spec: core.PodSpec{
-					ServiceAccountName: kube.ServiceAccountStarboard,
-					RestartPolicy:      core.RestartPolicyNever,
+				Spec: corev1.PodSpec{
+					ServiceAccountName: starboard.ServiceAccountName,
+					RestartPolicy:      corev1.RestartPolicyNever,
 					HostPID:            true,
-					Containers: []core.Container{
+					Containers: []corev1.Container{
 						{
 							Name:                     kubeHunterContainerName,
 							Image:                    kubeHunterContainerImage,
-							ImagePullPolicy:          core.PullIfNotPresent,
-							TerminationMessagePolicy: core.TerminationMessageFallbackToLogsOnError,
+							ImagePullPolicy:          corev1.PullIfNotPresent,
+							TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
 							Command:                  []string{"python", "kube-hunter.py"},
 							Args:                     []string{"--pod", "--report", "json", "--log", "warn"},
-							Resources: core.ResourceRequirements{
-								Limits: core.ResourceList{
-									core.ResourceCPU:    resource.MustParse("300m"),
-									core.ResourceMemory: resource.MustParse("400M"),
+							Resources: corev1.ResourceRequirements{
+								Limits: corev1.ResourceList{
+									corev1.ResourceCPU:    resource.MustParse("300m"),
+									corev1.ResourceMemory: resource.MustParse("400M"),
 								},
-								Requests: core.ResourceList{
-									core.ResourceCPU:    resource.MustParse("50m"),
-									core.ResourceMemory: resource.MustParse("100M"),
+								Requests: corev1.ResourceList{
+									corev1.ResourceCPU:    resource.MustParse("50m"),
+									corev1.ResourceMemory: resource.MustParse("100M"),
 								},
 							},
 						},
diff --git a/pkg/operator/aqua/scanner.go b/pkg/operator/aqua/scanner.go
index d8b326f..52ed789 100644
--- a/pkg/operator/aqua/scanner.go
+++ b/pkg/operator/aqua/scanner.go
@@ -3,6 +3,7 @@ package aqua
 import (
 	"encoding/json"
 	"fmt"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 	"io"
 
 	"k8s.io/apimachinery/pkg/api/resource"
@@ -26,11 +27,11 @@ const (
 )
 
 type aquaScanner struct {
-	version etc.VersionInfo
+	version starboard.BuildInfo
 	config  etc.ScannerAquaCSP
 }
 
-func NewScanner(version etc.VersionInfo, config etc.ScannerAquaCSP) scanner.VulnerabilityScanner {
+func NewScanner(version starboard.BuildInfo, config etc.ScannerAquaCSP) scanner.VulnerabilityScanner {
 	return &aquaScanner{
 		version: version,
 		config:  config,
diff --git a/pkg/operator/etc/config.go b/pkg/operator/etc/config.go
index 2e91a81..b29fcd6 100644
--- a/pkg/operator/etc/config.go
+++ b/pkg/operator/etc/config.go
@@ -12,12 +12,6 @@ const (
 	LabelPodSpecHash = "pod-spec-hash"
 )
 
-type VersionInfo struct {
-	Version string
-	Commit  string
-	Date    string
-}
-
 type Config struct {
 	Operator       Operator
 	ScannerAquaCSP ScannerAquaCSP
@@ -36,10 +30,13 @@ type Operator struct {
 
 type ScannerTrivy struct {
 	Enabled  bool   `env:"OPERATOR_SCANNER_TRIVY_ENABLED" envDefault:"true"`
-	Version  string `env:"OPERATOR_SCANNER_TRIVY_VERSION" envDefault:"0.11.0"`
 	ImageRef string `env:"OPERATOR_SCANNER_TRIVY_IMAGE" envDefault:"aquasec/trivy:0.11.0"`
 }
 
+func (c ScannerTrivy) GetTrivyImageRef() string {
+	return c.ImageRef
+}
+
 type ScannerAquaCSP struct {
 	Enabled  bool   `env:"OPERATOR_SCANNER_AQUA_CSP_ENABLED" envDefault:"false"`
 	Version  string `env:"OPERATOR_SCANNER_AQUA_CSP_VERSION" envDefault:"5.0"`
diff --git a/pkg/operator/scanner.go b/pkg/operator/scanner.go
index cb43534..a28ac1e 100644
--- a/pkg/operator/scanner.go
+++ b/pkg/operator/scanner.go
@@ -5,6 +5,8 @@ import (
 	"fmt"
 	"io"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"k8s.io/apimachinery/pkg/api/resource"
 
 	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
@@ -26,11 +28,11 @@ const (
 )
 
 type aquaScanner struct {
-	version etc.VersionInfo
+	version starboard.BuildInfo
 	config  etc.ScannerAquaCSP
 }
 
-func NewScanner(version etc.VersionInfo, config etc.ScannerAquaCSP) scanner.VulnerabilityScanner {
+func NewScanner(version starboard.BuildInfo, config etc.ScannerAquaCSP) scanner.VulnerabilityScanner {
 	return &aquaScanner{
 		version: version,
 		config:  config,
diff --git a/pkg/operator/trivy/scanner.go b/pkg/operator/trivy/scanner.go
index 3414642..c7d0389 100644
--- a/pkg/operator/trivy/scanner.go
+++ b/pkg/operator/trivy/scanner.go
@@ -140,11 +140,9 @@ func (s *trivyScanner) NewScanJob(meta scanner.JobMeta, options scanner.Options,
 }
 
 func (s *trivyScanner) ParseVulnerabilityScanResult(imageRef string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
-	result, err := trivy.DefaultConverter.Convert(imageRef, logsReader)
+	result, err := trivy.DefaultConverter.Convert(s.config, imageRef, logsReader)
 	if err != nil {
 		return v1alpha1.VulnerabilityScanResult{}, err
 	}
-	// TODO The Default converter has hardcoded version to 0.9.2
-	result.Scanner.Version = s.config.Version
 	return result, nil
 }
diff --git a/pkg/polaris/scanner.go b/pkg/polaris/scanner.go
index 3bb79ca..49b8662 100644
--- a/pkg/polaris/scanner.go
+++ b/pkg/polaris/scanner.go
@@ -4,9 +4,11 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/aquasecurity/starboard/pkg/scanners"
 
 	"k8s.io/utils/pointer"
@@ -50,7 +52,7 @@ func NewScanner(opts kube.ScannerOpts, clientset kubernetes.Interface) *Scanner
 	}
 }
 
-func (s *Scanner) Scan(ctx context.Context, workload kube.Object, gvk schema.GroupVersionKind) (report starboard.ConfigAudit, owner meta.Object, err error) {
+func (s *Scanner) Scan(ctx context.Context, workload kube.Object, gvk schema.GroupVersionKind) (report starboardv1alpha1.ConfigAudit, owner meta.Object, err error) {
 	_, owner, err = s.pods.GetPodSpecByWorkload(ctx, workload)
 	if err != nil {
 		return
@@ -111,7 +113,7 @@ func (s *Scanner) preparePolarisJob(workload kube.Object, gvk schema.GroupVersio
 	return &batch.Job{
 		ObjectMeta: meta.ObjectMeta{
 			Name:      uuid.New().String(),
-			Namespace: kube.NamespaceStarboard,
+			Namespace: starboard.NamespaceName,
 			Labels: map[string]string{
 				kube.LabelResourceKind:      string(workload.Kind),
 				kube.LabelResourceName:      workload.Name,
@@ -131,7 +133,7 @@ func (s *Scanner) preparePolarisJob(workload kube.Object, gvk schema.GroupVersio
 					},
 				},
 				Spec: core.PodSpec{
-					ServiceAccountName:           kube.ServiceAccountStarboard,
+					ServiceAccountName:           starboard.ServiceAccountName,
 					AutomountServiceAccountToken: pointer.BoolPtr(true),
 					RestartPolicy:                core.RestartPolicyNever,
 					Volumes: []core.Volume{
@@ -140,7 +142,7 @@ func (s *Scanner) preparePolarisJob(workload kube.Object, gvk schema.GroupVersio
 							VolumeSource: core.VolumeSource{
 								ConfigMap: &core.ConfigMapVolumeSource{
 									LocalObjectReference: core.LocalObjectReference{
-										Name: kube.ConfigMapStarboard,
+										Name: starboard.ConfigMapName,
 									},
 								},
 							},
diff --git a/pkg/starboard/config.go b/pkg/starboard/config.go
new file mode 100644
index 0000000..6ae7b4a
--- /dev/null
+++ b/pkg/starboard/config.go
@@ -0,0 +1,277 @@
+package starboard
+
+import (
+	"context"
+	"fmt"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/kubernetes"
+
+	"github.com/google/go-containerregistry/pkg/name"
+)
+
+const (
+	polarisConfigYAML = `checks:
+  # reliability
+  multipleReplicasForDeployment: ignore
+  priorityClassNotSet: ignore
+  # resources
+  cpuRequestsMissing: warning
+  cpuLimitsMissing: warning
+  memoryRequestsMissing: warning
+  memoryLimitsMissing: warning
+  # images
+  tagNotSpecified: danger
+  pullPolicyNotAlways: ignore
+  # healthChecks
+  readinessProbeMissing: warning
+  livenessProbeMissing: warning
+  # networking
+  hostNetworkSet: warning
+  hostPortSet: warning
+  # security
+  hostIPCSet: danger
+  hostPIDSet: danger
+  notReadOnlyRootFilesystem: warning
+  privilegeEscalationAllowed: danger
+  runAsRootAllowed: warning
+  runAsPrivileged: danger
+  dangerousCapabilities: danger
+  insecureCapabilities: warning
+exemptions:
+  - controllerNames:
+    - kube-apiserver
+    - kube-proxy
+    - kube-scheduler
+    - etcd-manager-events
+    - kube-controller-manager
+    - kube-dns
+    - etcd-manager-main
+    rules:
+    - hostPortSet
+    - hostNetworkSet
+    - readinessProbeMissing
+    - livenessProbeMissing
+    - cpuRequestsMissing
+    - cpuLimitsMissing
+    - memoryRequestsMissing
+    - memoryLimitsMissing
+    - runAsRootAllowed
+    - runAsPrivileged
+    - notReadOnlyRootFilesystem
+    - hostPIDSet
+  - controllerNames:
+    - kube-flannel-ds
+    rules:
+    - notReadOnlyRootFilesystem
+    - runAsRootAllowed
+    - notReadOnlyRootFilesystem
+    - readinessProbeMissing
+    - livenessProbeMissing
+    - cpuLimitsMissing
+  - controllerNames:
+    - cert-manager
+    rules:
+    - notReadOnlyRootFilesystem
+    - runAsRootAllowed
+    - readinessProbeMissing
+    - livenessProbeMissing
+  - controllerNames:
+    - cluster-autoscaler
+    rules:
+    - notReadOnlyRootFilesystem
+    - runAsRootAllowed
+    - readinessProbeMissing
+  - controllerNames:
+    - vpa
+    rules:
+    - runAsRootAllowed
+    - readinessProbeMissing
+    - livenessProbeMissing
+    - notReadOnlyRootFilesystem
+  - controllerNames:
+    - datadog
+    rules:
+    - runAsRootAllowed
+    - readinessProbeMissing
+    - livenessProbeMissing
+    - notReadOnlyRootFilesystem
+  - controllerNames:
+    - nginx-ingress-controller
+    rules:
+    - privilegeEscalationAllowed
+    - insecureCapabilities
+    - runAsRootAllowed
+  - controllerNames:
+    - dns-controller
+    - datadog-datadog
+    - kube-flannel-ds
+    - kube2iam
+    - aws-iam-authenticator
+    - datadog
+    - kube2iam
+    rules:
+    - hostNetworkSet
+  - controllerNames:
+    - aws-iam-authenticator
+    - aws-cluster-autoscaler
+    - kube-state-metrics
+    - dns-controller
+    - external-dns
+    - dnsmasq
+    - autoscaler
+    - kubernetes-dashboard
+    - install-cni
+    - kube2iam
+    rules:
+    - readinessProbeMissing
+    - livenessProbeMissing
+  - controllerNames:
+    - aws-iam-authenticator
+    - nginx-ingress-default-backend
+    - aws-cluster-autoscaler
+    - kube-state-metrics
+    - dns-controller
+    - external-dns
+    - kubedns
+    - dnsmasq
+    - autoscaler
+    - tiller
+    - kube2iam
+    rules:
+    - runAsRootAllowed
+  - controllerNames:
+    - aws-iam-authenticator
+    - nginx-ingress-controller
+    - nginx-ingress-default-backend
+    - aws-cluster-autoscaler
+    - kube-state-metrics
+    - dns-controller
+    - external-dns
+    - kubedns
+    - dnsmasq
+    - autoscaler
+    - tiller
+    - kube2iam
+    rules:
+    - notReadOnlyRootFilesystem
+  - controllerNames:
+    - cert-manager
+    - dns-controller
+    - kubedns
+    - dnsmasq
+    - autoscaler
+    - insights-agent-goldilocks-vpa-install
+    - datadog
+    rules:
+    - cpuRequestsMissing
+    - cpuLimitsMissing
+    - memoryRequestsMissing
+    - memoryLimitsMissing
+  - controllerNames:
+    - kube2iam
+    - kube-flannel-ds
+    rules:
+    - runAsPrivileged
+  - controllerNames:
+    - kube-hunter
+    rules:
+    - hostPIDSet
+  - controllerNames:
+    - polaris
+    - kube-hunter
+    - goldilocks
+    - insights-agent-goldilocks-vpa-install
+    rules:
+    - notReadOnlyRootFilesystem
+  - controllerNames:
+    - insights-agent-goldilocks-controller
+    rules:
+    - livenessProbeMissing
+    - readinessProbeMissing
+  - controllerNames:
+    - insights-agent-goldilocks-vpa-install
+    - kube-hunter
+    rules:
+    - runAsRootAllowed
+`
+)
+
+// BuildInfo holds build info such as Git revision, Git SHA-1,
+// and build datetime.
+type BuildInfo struct {
+	Version string
+	Commit  string
+	Date    string
+}
+
+// ConfigData holds Starboard configuration settings as a set
+// of key-value pairs.
+type ConfigData map[string]string
+
+type ConfigReader interface {
+	Read(ctx context.Context) (ConfigData, error)
+}
+
+// GetDefaultConfig returns the default configuration data.
+func GetDefaultConfig() ConfigData {
+	return map[string]string{
+		"trivy.severity":      "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL",
+		"trivy.imageRef":      "docker.io/aquasec/trivy:0.9.1",
+		"kube-bench.imageRef": "docker.io/aquasec/kube-bench:0.4.0",
+		"polaris.config.yaml": polarisConfigYAML,
+	}
+}
+
+func (c ConfigData) GetTrivyImageRef() string {
+	if imageRef, ok := c["trivy.imageRef"]; ok {
+		return imageRef
+	}
+	return "docker.io/aquasec/trivy:0.9.1"
+}
+
+// GetKubeBenchImageRef returns Docker image of kube-bench scanner.
+func (c ConfigData) GetKubeBenchImageRef() string {
+	if imageRef, ok := c["kube-bench.imageRef"]; ok {
+		return imageRef
+	}
+	return "docker.io/aquasec/kube-bench:0.4.0"
+}
+
+// GetVersionFromImageRef returns the image identifier for the specified image reference.
+func GetVersionFromImageRef(imageRef string) (string, error) {
+	ref, err := name.ParseReference(imageRef)
+	if err != nil {
+		return "", fmt.Errorf("parsing reference: %w", err)
+	}
+
+	var version string
+	switch t := ref.(type) {
+	case name.Tag:
+		version = t.TagStr()
+	case name.Digest:
+		version = t.DigestStr()
+	}
+
+	return version, nil
+}
+
+// NewConfigReader constructs a new ConfigReader that is using client-go
+// interfaces to read ConfigData from the ConfigMap.
+func NewConfigReader(client kubernetes.Interface) ConfigReader {
+	return &configReader{
+		client: client,
+	}
+}
+
+type configReader struct {
+	client kubernetes.Interface
+}
+
+func (c *configReader) Read(ctx context.Context) (ConfigData, error) {
+	cm, err := c.client.CoreV1().ConfigMaps(NamespaceName).Get(ctx, ConfigMapName, metav1.GetOptions{})
+	if err != nil {
+		return nil, err
+	}
+	return cm.Data, nil
+}
diff --git a/pkg/starboard/constants.go b/pkg/starboard/constants.go
new file mode 100644
index 0000000..e20e967
--- /dev/null
+++ b/pkg/starboard/constants.go
@@ -0,0 +1,14 @@
+package starboard
+
+const (
+	// NamespaceName the name of the namespace in which Starboard stores its
+	// configuration and runs scan Jobs.
+	NamespaceName = "starboard"
+
+	// ServiceAccountName the name of the ServiceAccount used to run scan Jobs.
+	ServiceAccountName = "starboard"
+
+	// ConfigMapName the name of the ConfigMap that stored configuration of
+	// Starboard and the underlying scanners.
+	ConfigMapName = "starboard"
+)


Test patch:
diff --git a/itest/starboard_cli_test.go b/itest/starboard_cli_test.go
index bf86f9d..28bbde1 100644
--- a/itest/starboard_cli_test.go
+++ b/itest/starboard_cli_test.go
@@ -841,7 +841,7 @@ var _ = Describe("Starboard CLI", func() {
 			err := cmd.Run(versionInfo, []string{
 				"starboard",
 				"kube-bench",
-				"-v", starboardCLILogLevel, "--namespace", namespaceItest,
+				"-v", starboardCLILogLevel,
 			}, GinkgoWriter, GinkgoWriter)
 			Expect(err).ToNot(HaveOccurred())
 
@@ -868,6 +868,13 @@ var _ = Describe("Starboard CLI", func() {
 							UID:        node.UID,
 						}),
 					}),
+					"Report": MatchFields(IgnoreExtras, Fields{
+						"Scanner": Equal(v1alpha1.Scanner{
+							Name:    "kube-bench",
+							Vendor:  "Aqua Security",
+							Version: "0.4.0",
+						}),
+					}),
 				}))
 			}
 		})
@@ -879,7 +886,7 @@ var _ = Describe("Starboard CLI", func() {
 			err := cmd.Run(versionInfo, []string{
 				"starboard",
 				"kube-hunter",
-				"-v", starboardCLILogLevel, "--namespace", namespaceItest,
+				"-v", starboardCLILogLevel,
 			}, GinkgoWriter, GinkgoWriter)
 			Expect(err).ToNot(HaveOccurred())
 
diff --git a/itest/suite_test.go b/itest/suite_test.go
index 1fa9b7f..fe8a75c 100644
--- a/itest/suite_test.go
+++ b/itest/suite_test.go
@@ -5,7 +5,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/aquasecurity/starboard/pkg/cmd"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/klog"
@@ -30,7 +30,7 @@ var (
 
 var (
 	starboardCLILogLevel = "0"
-	versionInfo          = cmd.VersionInfo{Version: "dev", Commit: "none", Date: "unknown"}
+	versionInfo          = starboard.BuildInfo{Version: "dev", Commit: "none", Date: "unknown"}
 )
 
 var (
diff --git a/pkg/find/vulnerabilities/trivy/converter_test.go b/pkg/find/vulnerabilities/trivy/converter_test.go
index 83f1e64..7703490 100644
--- a/pkg/find/vulnerabilities/trivy/converter_test.go
+++ b/pkg/find/vulnerabilities/trivy/converter_test.go
@@ -6,9 +6,11 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
 	"github.com/aquasecurity/starboard/pkg/find/vulnerabilities/trivy"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -45,33 +47,33 @@ var (
 	}
 ]`
 
-	sampleReport = starboard.VulnerabilityScanResult{
-		Scanner: starboard.Scanner{
+	sampleReport = starboardv1alpha1.VulnerabilityScanResult{
+		Scanner: starboardv1alpha1.Scanner{
 			Name:    "Trivy",
 			Vendor:  "Aqua Security",
 			Version: "0.9.1",
 		},
-		Registry: starboard.Registry{
+		Registry: starboardv1alpha1.Registry{
 			Server: "index.docker.io",
 		},
-		Artifact: starboard.Artifact{
+		Artifact: starboardv1alpha1.Artifact{
 			Repository: "library/alpine",
 			Tag:        "3.10.2",
 		},
-		Summary: starboard.VulnerabilitySummary{
+		Summary: starboardv1alpha1.VulnerabilitySummary{
 			CriticalCount: 0,
 			MediumCount:   1,
 			LowCount:      1,
 			NoneCount:     0,
 			UnknownCount:  0,
 		},
-		Vulnerabilities: []starboard.Vulnerability{
+		Vulnerabilities: []starboardv1alpha1.Vulnerability{
 			{
 				VulnerabilityID:  "CVE-2019-1549",
 				Resource:         "openssl",
 				InstalledVersion: "1.1.1c-r0",
 				FixedVersion:     "1.1.1d-r0",
-				Severity:         starboard.SeverityMedium,
+				Severity:         starboardv1alpha1.SeverityMedium,
 				Title:            "openssl: information disclosure in fork()",
 				Links: []string{
 					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549",
@@ -82,7 +84,7 @@ var (
 				Resource:         "openssl",
 				InstalledVersion: "1.1.1c-r0",
 				FixedVersion:     "1.1.1d-r0",
-				Severity:         starboard.SeverityLow,
+				Severity:         starboardv1alpha1.SeverityLow,
 				Title:            "openssl: side-channel weak encryption vulnerability",
 				Links: []string{
 					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547",
@@ -93,13 +95,16 @@ var (
 )
 
 func TestConverter_Convert(t *testing.T) {
+	config := starboard.ConfigData{
+		"trivy.imageRef": "aquasec/trivy:0.9.1",
+	}
 
 	testCases := []struct {
 		name           string
 		imageRef       string
 		input          string
 		expectedError  error
-		expectedReport starboard.VulnerabilityScanResult
+		expectedReport starboardv1alpha1.VulnerabilityScanResult
 	}{
 		{
 			name:     "Should convert vulnerability report in JSON format when input is noisy",
@@ -121,20 +126,20 @@ func TestConverter_Convert(t *testing.T) {
 			input: `2020-06-21T23:10:15.162+0200	WARN	OS is not detected and vulnerabilities in OS packages are not detected.
 null`,
 			expectedError: nil,
-			expectedReport: starboard.VulnerabilityScanResult{
-				Scanner: starboard.Scanner{
+			expectedReport: starboardv1alpha1.VulnerabilityScanResult{
+				Scanner: starboardv1alpha1.Scanner{
 					Name:    "Trivy",
 					Vendor:  "Aqua Security",
 					Version: "0.9.1",
 				},
-				Registry: starboard.Registry{
+				Registry: starboardv1alpha1.Registry{
 					Server: "core.harbor.domain",
 				},
-				Artifact: starboard.Artifact{
+				Artifact: starboardv1alpha1.Artifact{
 					Repository: "library/nginx",
 					Digest:     "sha256:d20aa6d1cae56fd17cd458f4807e0de462caf2336f0b70b5eeb69fcaaf30dd9c",
 				},
-				Summary: starboard.VulnerabilitySummary{
+				Summary: starboardv1alpha1.VulnerabilitySummary{
 					CriticalCount: 0,
 					HighCount:     0,
 					MediumCount:   0,
@@ -142,7 +147,7 @@ null`,
 					NoneCount:     0,
 					UnknownCount:  0,
 				},
-				Vulnerabilities: []starboard.Vulnerability{},
+				Vulnerabilities: []starboardv1alpha1.Vulnerability{},
 			},
 		},
 		{
@@ -155,7 +160,7 @@ null`,
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			report, err := trivy.NewConverter().Convert(tc.imageRef, strings.NewReader(tc.input))
+			report, err := trivy.NewConverter().Convert(config, tc.imageRef, strings.NewReader(tc.input))
 			switch {
 			case tc.expectedError == nil:
 				require.NoError(t, err)
diff --git a/pkg/kubebench/converter_test.go b/pkg/kubebench/converter_test.go
index 63c4b14..383b577 100644
--- a/pkg/kubebench/converter_test.go
+++ b/pkg/kubebench/converter_test.go
@@ -1,17 +1,23 @@
-package kubebench
+package kubebench_test
 
 import (
 	"encoding/json"
 	"errors"
+	"github.com/aquasecurity/starboard/pkg/kubebench"
 	"os"
 	"testing"
 
-	starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/starboard"
+
+	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestConverter_Convert(t *testing.T) {
+	config := starboard.ConfigData{
+		"kube-bench.imageRef": "aquasec/kube-bench:0.3.1",
+	}
 	var testcases = []struct {
 		name string
 		in   string // input File
@@ -45,8 +51,8 @@ func TestConverter_Convert(t *testing.T) {
 				_ = inFile.Close()
 			}()
 
-			var r starboard.CISKubeBenchOutput
-			r, err = DefaultConverter.Convert(inFile)
+			var r starboardv1alpha1.CISKubeBenchOutput
+			r, err = kubebench.DefaultConverter.Convert(config, inFile)
 
 			switch {
 			case tc.err == nil:
@@ -54,7 +60,7 @@ func TestConverter_Convert(t *testing.T) {
 				gFile, err := os.Open(tc.op)
 				require.NoError(t, err)
 				dec := json.NewDecoder(gFile)
-				var kbop starboard.CISKubeBenchOutput
+				var kbop starboardv1alpha1.CISKubeBenchOutput
 				err = dec.Decode(&kbop)
 				require.NoError(t, err)
 				defer func() {
diff --git a/pkg/starboard/config_test.go b/pkg/starboard/config_test.go
new file mode 100644
index 0000000..3d2a61d
--- /dev/null
+++ b/pkg/starboard/config_test.go
@@ -0,0 +1,122 @@
+package starboard_test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	"github.com/aquasecurity/starboard/pkg/starboard"
+	"github.com/stretchr/testify/assert"
+	"k8s.io/client-go/kubernetes/fake"
+)
+
+func TestGetVersionFromImageRef(t *testing.T) {
+	testCases := []struct {
+		imageRef        string
+		expectedVersion string
+	}{
+		{
+			imageRef:        "docker.io/aquasec/trivy:0.9.1",
+			expectedVersion: "0.9.1",
+		},
+		{
+			imageRef:        "docker.io/aquasec/trivy@sha256:5020dac24a63ef4f24452a0c63ebbfe93a5309e40f6353d1ee8221d2184ee954",
+			expectedVersion: "sha256:5020dac24a63ef4f24452a0c63ebbfe93a5309e40f6353d1ee8221d2184ee954",
+		},
+		{
+			imageRef:        "aquasec/trivy:0.9.1",
+			expectedVersion: "0.9.1",
+		},
+		{
+			imageRef:        "aquasec/trivy:latest",
+			expectedVersion: "latest",
+		},
+		{
+			imageRef:        "aquasec/trivy",
+			expectedVersion: "latest",
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.imageRef, func(t *testing.T) {
+			version, _ := starboard.GetVersionFromImageRef(tc.imageRef)
+			assert.Equal(t, tc.expectedVersion, version)
+		})
+	}
+}
+
+func TestConfigData_GetTrivyImageRef(t *testing.T) {
+	testCases := []struct {
+		name             string
+		configData       starboard.ConfigData
+		expectedImageRef string
+	}{
+		{
+			name:             "Should return default image reference",
+			configData:       starboard.ConfigData{},
+			expectedImageRef: "docker.io/aquasec/trivy:0.9.1",
+		},
+		{
+			name: "Should return image reference from config data",
+			configData: starboard.ConfigData{
+				"trivy.imageRef": "gcr.io/aquasecurity/trivy:0.8.0",
+			},
+			expectedImageRef: "gcr.io/aquasecurity/trivy:0.8.0",
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			imageRef := tc.configData.GetTrivyImageRef()
+			assert.Equal(t, tc.expectedImageRef, imageRef)
+		})
+	}
+}
+
+func TestConfigData_GetKubeBenchImageRef(t *testing.T) {
+	testCases := []struct {
+		name             string
+		configData       starboard.ConfigData
+		expectedImageRef string
+	}{
+		{
+			name:             "Should return default image reference",
+			configData:       starboard.ConfigData{},
+			expectedImageRef: "docker.io/aquasec/kube-bench:0.4.0",
+		},
+		{
+			name: "Should return image reference from config data",
+			configData: starboard.ConfigData{
+				"kube-bench.imageRef": "gcr.io/aquasecurity/kube-bench:0.4.0",
+			},
+			expectedImageRef: "gcr.io/aquasecurity/kube-bench:0.4.0",
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			imageRef := tc.configData.GetKubeBenchImageRef()
+			assert.Equal(t, tc.expectedImageRef, imageRef)
+		})
+	}
+}
+
+func TestConfigReader_Read(t *testing.T) {
+	clientset := fake.NewSimpleClientset(&corev1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: starboard.NamespaceName,
+			Name:      starboard.ConfigMapName,
+		},
+		Data: map[string]string{
+			"foo": "bar",
+		},
+	})
+	configData, err := starboard.NewConfigReader(clientset).Read(context.TODO())
+	require.NoError(t, err)
+	assert.Equal(t, starboard.ConfigData{
+		"foo": "bar",
+	}, configData)
+}
diff --git a/pkg/starboard/constants_test.go b/pkg/starboard/constants_test.go
new file mode 100644
index 0000000..9ca9617
--- /dev/null
+++ b/pkg/starboard/constants_test.go
@@ -0,0 +1,1 @@
+package starboard_test