Repository: aquasecurity/starboard
Pull request #547 (2021-05-01 17:24:35)

feat(trivy): Pass additional settings to Trivy client
Resolves: https://github.com/aquasecurity/starboard/issues/541

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) Report
> Merging [#547](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) (0ebec17) into [main](https://codecov.io/gh/aquasecurity/starboard/commit/cf2ef217eda4bf097c591e38db122d2d3d2e5d2c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) (cf2ef21) will **decrease** coverage by `17.15%`.
> The diff coverage is `36.42%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/547/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)

```diff
@@             Coverage Diff             @@
##             main     #547       +/-   ##
===========================================
- Coverage   70.79%   53.63%   -17.16%     
===========================================
  Files          63       22       -41     
  Lines        4054     2405     -1649     
===========================================
- Hits         2870     1290     -1580     
- Misses        868      985      +117     
+ Partials      316      130      -186     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) | Coverage Δ | |
|---|---|---|
| [pkg/plugin/trivy/plugin.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3BsdWdpbi90cml2eS9wbHVnaW4uZ28=) | `44.21% <36.42%> (-35.68%)` | :arrow_down: |
| [pkg/plugin/conftest/plugin.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3BsdWdpbi9jb25mdGVzdC9wbHVnaW4uZ28=) | `0.00% <0.00%> (-87.50%)` | :arrow_down: |
| [pkg/vulnerabilityreport/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3Z1bG5lcmFiaWxpdHlyZXBvcnQvc2Nhbm5lci5nbw==) | `0.00% <0.00%> (-74.23%)` | :arrow_down: |
| [pkg/configauditreport/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2NvbmZpZ2F1ZGl0cmVwb3J0L3NjYW5uZXIuZ28=) | `0.00% <0.00%> (-73.22%)` | :arrow_down: |
| [pkg/vulnerabilityreport/sort.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3Z1bG5lcmFiaWxpdHlyZXBvcnQvc29ydC5nbw==) | `0.00% <0.00%> (-71.43%)` | :arrow_down: |
| [pkg/vulnerabilityreport/io.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3Z1bG5lcmFiaWxpdHlyZXBvcnQvaW8uZ28=) | `41.86% <0.00%> (-32.56%)` | :arrow_down: |
| [pkg/kubebench/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2t1YmViZW5jaC9zY2FubmVyLmdv) | `63.98% <0.00%> (-26.07%)` | :arrow_down: |
| [pkg/kubebench/io.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2t1YmViZW5jaC9pby5nbw==) | `69.56% <0.00%> (-21.74%)` | :arrow_down: |
| [pkg/configauditreport/io.go](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2NvbmZpZ2F1ZGl0cmVwb3J0L2lvLmdv) | `43.90% <0.00%> (-12.20%)` | :arrow_down: |
| ... and [48 more](https://codecov.io/gh/aquasecurity/starboard/pull/547/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity). Last update [cf2ef21...0ebec17](https://codecov.io/gh/aquasecurity/starboard/pull/547?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity).

xyoxo: > @xyoxo Please rebase this PR

@danielpacak Rebased.

Patch:
diff --git a/docs/settings.md b/docs/settings.md
index 73a9219..e1f972c 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -56,7 +56,7 @@ The following tables list available configuration settings with their default va
     used if `vulnerabilityReports.scanner` is set to `Trivy`). Check
     [integrations](./integrations/vulnerability-scanners/index.md) page to see example configuration settings for common use cases.
 
-| CONFIGMAP KEY                         | DEFAULT                                                                           | DESCRIPTION |
+| CONFIGMAP KEY                   | DEFAULT                                                | DESCRIPTION |
 | ------------------------------- | ------------------------------------------------------ | ----------- |
 | `vulnerabilityReports.scanner`  | `Trivy`                                                | The name of the plugin that generates vulnerability reports. Either `Trivy` or `Aqua`. |
 | `configAuditReports.scanner`    | `Polaris`                                              | The name of the plugin that generates config audit reports. Either `Polaris` or `Conftest`. |
@@ -66,6 +66,10 @@ The following tables list available configuration settings with their default va
 | `trivy.severity`                | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL`                     | A comma separated list of severity levels reported by Trivy |
 | `trivy.imageRef`                | `docker.io/aquasec/trivy:0.16.0`                       | Trivy image reference |
 | `trivy.mode`                    | `Standalone`                                           | Trivy client mode. Either `Standalone` or `ClientServer`. Depending on the active mode other settings might be applicable or required. |
+| `trivy.ignoreUnfixed`           | N/A                                                    | Whether to show only fixed vulnerabilities in vulnerabilities reported by Trivy. Set to `"true"` to enable it. |
+| `trivy.skipFiles`               | N/A                                                    | A comma separated list of file paths for Trivy to skip traversal. |
+| `trivy.skipDirs`                | N/A                                                    | A comma separated list of directories for Trivy to skip traversal. |
+| `trivy.ignoreFile`              | N/A                                                    | It specifies the `.trivyignore` file which contains a list of vulnerability IDs to be ignored from vulnerabilities reported by Trivy. |
 | `trivy.serverURL`               | N/A                                                    | The endpoint URL of the Trivy server. Required in `ClientServer` mode. |
 | `trivy.serverTokenHeader`       | `Trivy-Token`                                          | The name of the HTTP header to send the authentication token to Trivy server. Only application in `ClientServer` mode when `trivy.serverToken` is specified. |
 | `trivy.insecureRegistry.<id>`   | N/A                                                    | The registry to which insecure connections are allowed. There can be multiple registries with different registry `<id>`. |
@@ -77,7 +81,7 @@ The following tables list available configuration settings with their default va
 | `polaris.imageRef`              | `quay.io/fairwinds/polaris:3.2`                        | Polaris image reference |
 | `polaris.config.yaml`           | [Check the default value here][default-polaris-config] | Polaris configuration file |
 | `conftest.imageRef`             | `docker.io/openpolicyagent/conftest:v0.25.0`           | Conftest image reference |
-| `scanJob.tolerations`           |                                                        | JSON representation of the [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) to be applied to the vulnerability scanner pods so that they can run on nodes with matching taints. Example: `'[{"key":"key1", "operator":"Equal", "value":"value1", "effect":"NoSchedule"}]'`|
+| `scanJob.tolerations`           | N/A                                                    | JSON representation of the [tolerations] to be applied to the vulnerability scanner pods so that they can run on nodes with matching taints. Example: `'[{"key":"key1", "operator":"Equal", "value":"value1", "effect":"NoSchedule"}]'`|
 
 | SECRET KEY                  | DESCRIPTION |
 | --------------------------- | ----------- |
@@ -97,3 +101,4 @@ The following tables list available configuration settings with their default va
     ```
 
 [default-polaris-config]: https://raw.githubusercontent.com/aquasecurity/starboard/{{ var.tag }}/deploy/static/05-starboard-operator.config.yaml
+[tolerations]: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
\ No newline at end of file
diff --git a/pkg/plugin/trivy/plugin.go b/pkg/plugin/trivy/plugin.go
index 3869e8d..56d0c86 100644
--- a/pkg/plugin/trivy/plugin.go
+++ b/pkg/plugin/trivy/plugin.go
@@ -42,6 +42,7 @@ type Config interface {
 	GetTrivyMode() (starboard.TrivyMode, error)
 	GetTrivyServerURL() (string, error)
 	GetTrivyInsecureRegistries() map[string]bool
+	TrivyIgnoreFileExists() bool
 }
 
 // NewPlugin constructs a new vulnerabilityreport.Plugin, which is using an
@@ -88,7 +89,8 @@ func (s *scanner) newSecretWithAggregateImagePullCredentials(spec corev1.PodSpec
 }
 
 const (
-	sharedVolumeName = "data"
+	sharedVolumeName     = "data"
+	ignoreFileVolumeName = "ignorefile"
 )
 
 // In the starboard.Standalone mode there is the init container responsible for
@@ -193,6 +195,49 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 
 	var containers []corev1.Container
 
+	volumeMounts := []corev1.VolumeMount{
+		{
+			Name:      sharedVolumeName,
+			ReadOnly:  false,
+			MountPath: "/var/lib/trivy",
+		},
+	}
+	volumes := []corev1.Volume{
+		{
+			Name: sharedVolumeName,
+			VolumeSource: corev1.VolumeSource{
+				EmptyDir: &corev1.EmptyDirVolumeSource{
+					Medium: corev1.StorageMediumDefault,
+				},
+			},
+		},
+	}
+
+	if s.config.TrivyIgnoreFileExists() {
+		volumes = append(volumes, corev1.Volume{
+			Name: ignoreFileVolumeName,
+			VolumeSource: corev1.VolumeSource{
+				ConfigMap: &corev1.ConfigMapVolumeSource{
+					LocalObjectReference: corev1.LocalObjectReference{
+						Name: starboard.ConfigMapName,
+					},
+					Items: []corev1.KeyToPath{
+						{
+							Key:  "trivy.ignoreFile",
+							Path: ".trivyignore",
+						},
+					},
+				},
+			},
+		})
+
+		volumeMounts = append(volumeMounts, corev1.VolumeMount{
+			Name:      ignoreFileVolumeName,
+			MountPath: "/tmp/trivy/.trivyignore",
+			SubPath:   ".trivyignore",
+		})
+	}
+
 	for _, c := range spec.Containers {
 
 		env := []corev1.EnvVar{
@@ -208,6 +253,42 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 					},
 				},
 			},
+			{
+				Name: "TRIVY_IGNORE_UNFIXED",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.ignoreUnfixed",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
+			{
+				Name: "TRIVY_SKIP_FILES",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.skipFiles",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
+			{
+				Name: "TRIVY_SKIP_DIRS",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.skipDirs",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
 			{
 				Name: "HTTP_PROXY",
 				ValueFrom: &corev1.EnvVarSource{
@@ -246,6 +327,13 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 			},
 		}
 
+		if s.config.TrivyIgnoreFileExists() {
+			env = append(env, corev1.EnvVar{
+				Name:  "TRIVY_IGNOREFILE",
+				Value: "/tmp/trivy/.trivyignore",
+			})
+		}
+
 		if _, ok := credentials[c.Name]; ok && secret != nil {
 			registryUsernameKey := fmt.Sprintf("%s.username", c.Name)
 			registryPasswordKey := fmt.Sprintf("%s.password", c.Name)
@@ -296,14 +384,8 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 				"json",
 				c.Image,
 			},
-			Resources: defaultResourceRequirements,
-			VolumeMounts: []corev1.VolumeMount{
-				{
-					Name:      sharedVolumeName,
-					ReadOnly:  false,
-					MountPath: "/var/lib/trivy",
-				},
-			},
+			Resources:    defaultResourceRequirements,
+			VolumeMounts: volumeMounts,
 			SecurityContext: &corev1.SecurityContext{
 				Privileged:               pointer.BoolPtr(false),
 				AllowPrivilegeEscalation: pointer.BoolPtr(false),
@@ -319,19 +401,10 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 		Affinity:                     starboard.LinuxNodeAffinity(),
 		RestartPolicy:                corev1.RestartPolicyNever,
 		AutomountServiceAccountToken: pointer.BoolPtr(false),
-		Volumes: []corev1.Volume{
-			{
-				Name: sharedVolumeName,
-				VolumeSource: corev1.VolumeSource{
-					EmptyDir: &corev1.EmptyDirVolumeSource{
-						Medium: corev1.StorageMediumDefault,
-					},
-				},
-			},
-		},
-		InitContainers:  []corev1.Container{initContainer},
-		Containers:      containers,
-		SecurityContext: &corev1.PodSecurityContext{},
+		Volumes:                      volumes,
+		InitContainers:               []corev1.Container{initContainer},
+		Containers:                   containers,
+		SecurityContext:              &corev1.PodSecurityContext{},
 	}, secrets, nil
 }
 
@@ -345,6 +418,8 @@ func (s *scanner) getPodSpecForStandaloneMode(spec corev1.PodSpec, credentials m
 func (s *scanner) getPodSpecForClientServerMode(spec corev1.PodSpec, credentials map[string]docker.Auth) (corev1.PodSpec, []*corev1.Secret, error) {
 	var secret *corev1.Secret
 	var secrets []*corev1.Secret
+	var volumeMounts []corev1.VolumeMount
+	var volumes []corev1.Volume
 
 	trivyImageRef, err := s.config.GetTrivyImageRef()
 	if err != nil {
@@ -414,6 +489,42 @@ func (s *scanner) getPodSpecForClientServerMode(spec corev1.PodSpec, credentials
 					},
 				},
 			},
+			{
+				Name: "TRIVY_IGNORE_UNFIXED",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.ignoreUnfixed",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
+			{
+				Name: "TRIVY_SKIP_FILES",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.skipFiles",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
+			{
+				Name: "TRIVY_SKIP_DIRS",
+				ValueFrom: &corev1.EnvVarSource{
+					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+						LocalObjectReference: corev1.LocalObjectReference{
+							Name: starboard.ConfigMapName,
+						},
+						Key:      "trivy.skipDirs",
+						Optional: pointer.BoolPtr(true),
+					},
+				},
+			},
 			{
 				Name: "TRIVY_TOKEN_HEADER",
 				ValueFrom: &corev1.EnvVarSource{
@@ -484,6 +595,40 @@ func (s *scanner) getPodSpecForClientServerMode(spec corev1.PodSpec, credentials
 			return corev1.PodSpec{}, nil, err
 		}
 
+		if s.config.TrivyIgnoreFileExists() {
+			volumes = []corev1.Volume{
+				{
+					Name: ignoreFileVolumeName,
+					VolumeSource: corev1.VolumeSource{
+						ConfigMap: &corev1.ConfigMapVolumeSource{
+							LocalObjectReference: corev1.LocalObjectReference{
+								Name: starboard.ConfigMapName,
+							},
+							Items: []corev1.KeyToPath{
+								{
+									Key:  "trivy.ignoreFile",
+									Path: ".trivyignore",
+								},
+							},
+						},
+					},
+				},
+			}
+
+			volumeMounts = []corev1.VolumeMount{
+				{
+					Name:      ignoreFileVolumeName,
+					MountPath: "/tmp/trivy/.trivyignore",
+					SubPath:   ".trivyignore",
+				},
+			}
+
+			env = append(env, corev1.EnvVar{
+				Name:  "TRIVY_IGNOREFILE",
+				Value: "/tmp/trivy/.trivyignore",
+			})
+		}
+
 		containers = append(containers, corev1.Container{
 			Name:                     container.Name,
 			Image:                    trivyImageRef,
@@ -502,7 +647,8 @@ func (s *scanner) getPodSpecForClientServerMode(spec corev1.PodSpec, credentials
 				trivyServerURL,
 				container.Image,
 			},
-			Resources: defaultResourceRequirements,
+			VolumeMounts: volumeMounts,
+			Resources:    defaultResourceRequirements,
 		})
 	}
 
@@ -510,6 +656,7 @@ func (s *scanner) getPodSpecForClientServerMode(spec corev1.PodSpec, credentials
 		RestartPolicy:                corev1.RestartPolicyNever,
 		AutomountServiceAccountToken: pointer.BoolPtr(false),
 		Containers:                   containers,
+		Volumes:                      volumes,
 	}, secrets, nil
 }
 
diff --git a/pkg/starboard/config.go b/pkg/starboard/config.go
index 61055d7..8988bd9 100644
--- a/pkg/starboard/config.go
+++ b/pkg/starboard/config.go
@@ -368,6 +368,12 @@ func (c ConfigData) GetTrivyServerURL() (string, error) {
 	return c.getRequiredProperty(keyTrivyServerURL)
 }
 
+func (c ConfigData) TrivyIgnoreFileExists() bool {
+	_, ok := c["trivy.ignoreFile"]
+
+	return ok
+}
+
 func (c ConfigData) GetTrivyInsecureRegistries() map[string]bool {
 	insecureRegistries := make(map[string]bool)
 	for key, val := range c {


Test patch:
diff --git a/pkg/plugin/trivy/plugin_test.go b/pkg/plugin/trivy/plugin_test.go
index 7ab86f6..cbeda12 100644
--- a/pkg/plugin/trivy/plugin_test.go
+++ b/pkg/plugin/trivy/plugin_test.go
@@ -141,18 +141,55 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 						Image:                    "docker.io/aquasec/trivy:0.14.0",
 						ImagePullPolicy:          corev1.PullIfNotPresent,
 						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
-						Env: []corev1.EnvVar{{
-							Name: "TRIVY_SEVERITY",
-							ValueFrom: &corev1.EnvVarSource{
-								ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
-									LocalObjectReference: corev1.LocalObjectReference{
-										Name: starboard.ConfigMapName,
+						Env: []corev1.EnvVar{
+							{
+								Name: "TRIVY_SEVERITY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.severity",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_IGNORE_UNFIXED",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.ignoreUnfixed",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_FILES",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipFiles",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_DIRS",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
 									},
-									Key:      "trivy.severity",
-									Optional: pointer.BoolPtr(true),
 								},
 							},
-						},
 							{
 								Name: "HTTP_PROXY",
 								ValueFrom: &corev1.EnvVarSource{
@@ -347,18 +384,55 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 						Image:                    "docker.io/aquasec/trivy:0.14.0",
 						ImagePullPolicy:          corev1.PullIfNotPresent,
 						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
-						Env: []corev1.EnvVar{{
-							Name: "TRIVY_SEVERITY",
-							ValueFrom: &corev1.EnvVarSource{
-								ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
-									LocalObjectReference: corev1.LocalObjectReference{
-										Name: starboard.ConfigMapName,
+						Env: []corev1.EnvVar{
+							{
+								Name: "TRIVY_SEVERITY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.severity",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_IGNORE_UNFIXED",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.ignoreUnfixed",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_FILES",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipFiles",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_DIRS",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
 									},
-									Key:      "trivy.severity",
-									Optional: pointer.BoolPtr(true),
 								},
 							},
-						},
 							{
 								Name: "HTTP_PROXY",
 								ValueFrom: &corev1.EnvVarSource{
@@ -441,11 +515,15 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 			},
 		},
 		{
-			name: "ClientServer mode without insecure registry",
+			name: "Standalone mode with trivyignore file",
 			config: starboard.ConfigData{
-				"trivy.imageRef":  "docker.io/aquasec/trivy:0.14.0",
-				"trivy.mode":      string(starboard.ClientServer),
-				"trivy.serverURL": "http://trivy.trivy:4954",
+				"trivy.imageRef": "docker.io/aquasec/trivy:0.14.0",
+				"trivy.mode":     string(starboard.Standalone),
+				"trivy.ignoreFile": `# Accept the risk
+CVE-2018-14618
+
+# No impact in our settings
+CVE-2019-1543`,
 			},
 			workloadSpec: corev1.PodSpec{
 				Containers: []corev1.Container{
@@ -456,11 +534,38 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 				},
 			},
 			expectedJobSpec: corev1.PodSpec{
+				Affinity:                     starboard.LinuxNodeAffinity(),
 				RestartPolicy:                corev1.RestartPolicyNever,
 				AutomountServiceAccountToken: pointer.BoolPtr(false),
-				Containers: []corev1.Container{
+				Volumes: []corev1.Volume{
 					{
-						Name:                     "nginx",
+						Name: "data",
+						VolumeSource: corev1.VolumeSource{
+							EmptyDir: &corev1.EmptyDirVolumeSource{
+								Medium: corev1.StorageMediumDefault,
+							},
+						},
+					},
+					{
+						Name: "ignorefile",
+						VolumeSource: corev1.VolumeSource{
+							ConfigMap: &corev1.ConfigMapVolumeSource{
+								LocalObjectReference: corev1.LocalObjectReference{
+									Name: starboard.ConfigMapName,
+								},
+								Items: []corev1.KeyToPath{
+									{
+										Key:  "trivy.ignoreFile",
+										Path: ".trivyignore",
+									},
+								},
+							},
+						},
+					},
+				},
+				InitContainers: []corev1.Container{
+					{
+						Name:                     "00000000-0000-0000-0000-000000000001",
 						Image:                    "docker.io/aquasec/trivy:0.14.0",
 						ImagePullPolicy:          corev1.PullIfNotPresent,
 						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
@@ -501,6 +606,53 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 									},
 								},
 							},
+
+							{
+								Name: "GITHUB_TOKEN",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.githubToken",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+						},
+						Command: []string{
+							"trivy",
+						},
+						Args: []string{
+							"--download-db-only",
+							"--cache-dir", "/var/lib/trivy",
+						},
+						Resources: corev1.ResourceRequirements{
+							Requests: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("100m"),
+								corev1.ResourceMemory: resource.MustParse("100M"),
+							},
+							Limits: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("500m"),
+								corev1.ResourceMemory: resource.MustParse("500M"),
+							},
+						},
+						VolumeMounts: []corev1.VolumeMount{
+							{
+								Name:      "data",
+								MountPath: "/var/lib/trivy",
+								ReadOnly:  false,
+							},
+						},
+					},
+				},
+				Containers: []corev1.Container{
+					{
+						Name:                     "nginx",
+						Image:                    "docker.io/aquasec/trivy:0.14.0",
+						ImagePullPolicy:          corev1.PullIfNotPresent,
+						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
+						Env: []corev1.EnvVar{
 							{
 								Name: "TRIVY_SEVERITY",
 								ValueFrom: &corev1.EnvVarSource{
@@ -514,52 +666,90 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 								},
 							},
 							{
-								Name: "TRIVY_TOKEN_HEADER",
+								Name: "TRIVY_IGNORE_UNFIXED",
 								ValueFrom: &corev1.EnvVarSource{
 									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
 										LocalObjectReference: corev1.LocalObjectReference{
-											Name: starboard.SecretName,
+											Name: starboard.ConfigMapName,
 										},
-										Key:      "trivy.serverTokenHeader",
+										Key:      "trivy.ignoreUnfixed",
 										Optional: pointer.BoolPtr(true),
 									},
 								},
 							},
 							{
-								Name: "TRIVY_TOKEN",
+								Name: "TRIVY_SKIP_FILES",
 								ValueFrom: &corev1.EnvVarSource{
-									SecretKeyRef: &corev1.SecretKeySelector{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
 										LocalObjectReference: corev1.LocalObjectReference{
-											Name: starboard.SecretName,
+											Name: starboard.ConfigMapName,
 										},
-										Key:      "trivy.serverToken",
+										Key:      "trivy.skipFiles",
 										Optional: pointer.BoolPtr(true),
 									},
 								},
 							},
 							{
-								Name: "TRIVY_CUSTOM_HEADERS",
+								Name: "TRIVY_SKIP_DIRS",
 								ValueFrom: &corev1.EnvVarSource{
-									SecretKeyRef: &corev1.SecretKeySelector{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
 										LocalObjectReference: corev1.LocalObjectReference{
-											Name: starboard.SecretName,
+											Name: starboard.ConfigMapName,
 										},
-										Key:      "trivy.serverCustomHeaders",
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "HTTP_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "HTTPS_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpsProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "NO_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.noProxy",
 										Optional: pointer.BoolPtr(true),
 									},
 								},
 							},
+							{
+								Name:  "TRIVY_IGNOREFILE",
+								Value: "/tmp/trivy/.trivyignore",
+							},
 						},
 						Command: []string{
 							"trivy",
 						},
 						Args: []string{
+							"--skip-update",
+							"--cache-dir", "/var/lib/trivy",
 							"--quiet",
-							"client",
-							"--format",
-							"json",
-							"--remote",
-							"http://trivy.trivy:4954",
+							"--format", "json",
 							"nginx:1.16",
 						},
 						Resources: corev1.ResourceRequirements{
@@ -572,23 +762,43 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 								corev1.ResourceMemory: resource.MustParse("500M"),
 							},
 						},
+						VolumeMounts: []corev1.VolumeMount{
+							{
+								Name:      "data",
+								ReadOnly:  false,
+								MountPath: "/var/lib/trivy",
+							},
+							{
+								Name:      "ignorefile",
+								MountPath: "/tmp/trivy/.trivyignore",
+								SubPath:   ".trivyignore",
+							},
+						},
+						SecurityContext: &corev1.SecurityContext{
+							Privileged:               pointer.BoolPtr(false),
+							AllowPrivilegeEscalation: pointer.BoolPtr(false),
+							Capabilities: &corev1.Capabilities{
+								Drop: []corev1.Capability{"all"},
+							},
+							ReadOnlyRootFilesystem: pointer.BoolPtr(true),
+						},
 					},
 				},
+				SecurityContext: &corev1.PodSecurityContext{},
 			},
 		},
 		{
-			name: "ClientServer mode with insecure registry",
+			name: "ClientServer mode without insecure registry",
 			config: starboard.ConfigData{
-				"trivy.imageRef":                     "docker.io/aquasec/trivy:0.14.0",
-				"trivy.mode":                         string(starboard.ClientServer),
-				"trivy.serverURL":                    "http://trivy.trivy:4954",
-				"trivy.insecureRegistry.pocRegistry": "poc.myregistry.harbor.com.pl",
+				"trivy.imageRef":  "docker.io/aquasec/trivy:0.14.0",
+				"trivy.mode":      string(starboard.ClientServer),
+				"trivy.serverURL": "http://trivy.trivy:4954",
 			},
 			workloadSpec: corev1.PodSpec{
 				Containers: []corev1.Container{
 					{
 						Name:  "nginx",
-						Image: "poc.myregistry.harbor.com.pl/nginx:1.16",
+						Image: "nginx:1.16",
 					},
 				},
 			},
@@ -651,21 +861,230 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 								},
 							},
 							{
-								Name: "TRIVY_TOKEN_HEADER",
+								Name: "TRIVY_IGNORE_UNFIXED",
 								ValueFrom: &corev1.EnvVarSource{
 									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
 										LocalObjectReference: corev1.LocalObjectReference{
-											Name: starboard.SecretName,
+											Name: starboard.ConfigMapName,
 										},
-										Key:      "trivy.serverTokenHeader",
+										Key:      "trivy.ignoreUnfixed",
 										Optional: pointer.BoolPtr(true),
 									},
 								},
 							},
 							{
-								Name: "TRIVY_TOKEN",
+								Name: "TRIVY_SKIP_FILES",
 								ValueFrom: &corev1.EnvVarSource{
-									SecretKeyRef: &corev1.SecretKeySelector{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipFiles",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_DIRS",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN_HEADER",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverTokenHeader",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverToken",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_CUSTOM_HEADERS",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverCustomHeaders",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+						},
+						Command: []string{
+							"trivy",
+						},
+						Args: []string{
+							"--quiet",
+							"client",
+							"--format",
+							"json",
+							"--remote",
+							"http://trivy.trivy:4954",
+							"nginx:1.16",
+						},
+						Resources: corev1.ResourceRequirements{
+							Requests: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("100m"),
+								corev1.ResourceMemory: resource.MustParse("100M"),
+							},
+							Limits: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("500m"),
+								corev1.ResourceMemory: resource.MustParse("500M"),
+							},
+						},
+					},
+				},
+			},
+		},
+		{
+			name: "ClientServer mode with insecure registry",
+			config: starboard.ConfigData{
+				"trivy.imageRef":                     "docker.io/aquasec/trivy:0.14.0",
+				"trivy.mode":                         string(starboard.ClientServer),
+				"trivy.serverURL":                    "http://trivy.trivy:4954",
+				"trivy.insecureRegistry.pocRegistry": "poc.myregistry.harbor.com.pl",
+			},
+			workloadSpec: corev1.PodSpec{
+				Containers: []corev1.Container{
+					{
+						Name:  "nginx",
+						Image: "poc.myregistry.harbor.com.pl/nginx:1.16",
+					},
+				},
+			},
+			expectedJobSpec: corev1.PodSpec{
+				RestartPolicy:                corev1.RestartPolicyNever,
+				AutomountServiceAccountToken: pointer.BoolPtr(false),
+				Containers: []corev1.Container{
+					{
+						Name:                     "nginx",
+						Image:                    "docker.io/aquasec/trivy:0.14.0",
+						ImagePullPolicy:          corev1.PullIfNotPresent,
+						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
+						Env: []corev1.EnvVar{
+							{
+								Name: "HTTP_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "HTTPS_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpsProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "NO_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.noProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SEVERITY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.severity",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_IGNORE_UNFIXED",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.ignoreUnfixed",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_FILES",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipFiles",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_DIRS",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN_HEADER",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverTokenHeader",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
 										LocalObjectReference: corev1.LocalObjectReference{
 											Name: starboard.SecretName,
 										},
@@ -717,6 +1136,212 @@ func TestScanner_GetScanJobSpec(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "ClientServer mode with trivyignore file",
+			config: starboard.ConfigData{
+				"trivy.imageRef":  "docker.io/aquasec/trivy:0.14.0",
+				"trivy.mode":      string(starboard.ClientServer),
+				"trivy.serverURL": "http://trivy.trivy:4954",
+				"trivy.ignoreFile": `# Accept the risk
+CVE-2018-14618
+
+# No impact in our settings
+CVE-2019-1543`,
+			},
+			workloadSpec: corev1.PodSpec{
+				Containers: []corev1.Container{
+					{
+						Name:  "nginx",
+						Image: "nginx:1.16",
+					},
+				},
+			},
+			expectedJobSpec: corev1.PodSpec{
+				RestartPolicy:                corev1.RestartPolicyNever,
+				AutomountServiceAccountToken: pointer.BoolPtr(false),
+				Volumes: []corev1.Volume{
+					{
+						Name: "ignorefile",
+						VolumeSource: corev1.VolumeSource{
+							ConfigMap: &corev1.ConfigMapVolumeSource{
+								LocalObjectReference: corev1.LocalObjectReference{
+									Name: starboard.ConfigMapName,
+								},
+								Items: []corev1.KeyToPath{
+									{
+										Key:  "trivy.ignoreFile",
+										Path: ".trivyignore",
+									},
+								},
+							},
+						},
+					},
+				},
+				Containers: []corev1.Container{
+					{
+						Name:                     "nginx",
+						Image:                    "docker.io/aquasec/trivy:0.14.0",
+						ImagePullPolicy:          corev1.PullIfNotPresent,
+						TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
+						Env: []corev1.EnvVar{
+							{
+								Name: "HTTP_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "HTTPS_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.httpsProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "NO_PROXY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.noProxy",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SEVERITY",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.severity",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_IGNORE_UNFIXED",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.ignoreUnfixed",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_FILES",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipFiles",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_SKIP_DIRS",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.ConfigMapName,
+										},
+										Key:      "trivy.skipDirs",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN_HEADER",
+								ValueFrom: &corev1.EnvVarSource{
+									ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverTokenHeader",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_TOKEN",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverToken",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name: "TRIVY_CUSTOM_HEADERS",
+								ValueFrom: &corev1.EnvVarSource{
+									SecretKeyRef: &corev1.SecretKeySelector{
+										LocalObjectReference: corev1.LocalObjectReference{
+											Name: starboard.SecretName,
+										},
+										Key:      "trivy.serverCustomHeaders",
+										Optional: pointer.BoolPtr(true),
+									},
+								},
+							},
+							{
+								Name:  "TRIVY_IGNOREFILE",
+								Value: "/tmp/trivy/.trivyignore",
+							},
+						},
+						Command: []string{
+							"trivy",
+						},
+						Args: []string{
+							"--quiet",
+							"client",
+							"--format",
+							"json",
+							"--remote",
+							"http://trivy.trivy:4954",
+							"nginx:1.16",
+						},
+						Resources: corev1.ResourceRequirements{
+							Requests: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("100m"),
+								corev1.ResourceMemory: resource.MustParse("100M"),
+							},
+							Limits: corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("500m"),
+								corev1.ResourceMemory: resource.MustParse("500M"),
+							},
+						},
+						VolumeMounts: []corev1.VolumeMount{
+							{
+								Name:      "ignorefile",
+								MountPath: "/tmp/trivy/.trivyignore",
+								SubPath:   ".trivyignore",
+							},
+						},
+					},
+				},
+			},
+		},
 	}
 
 	for _, tc := range testCases {
diff --git a/pkg/starboard/config_test.go b/pkg/starboard/config_test.go
index 93c9093..0d6da00 100644
--- a/pkg/starboard/config_test.go
+++ b/pkg/starboard/config_test.go
@@ -669,3 +669,38 @@ func TestGetScanJobTolerations(t *testing.T) {
 		assert.Equal(t, tc.expected, got, tc.name)
 	}
 }
+
+func TestConfigData_TrivyIgnoreFileExists(t *testing.T) {
+	testCases := []struct {
+		name           string
+		configData     starboard.ConfigData
+		expectedOutput bool
+	}{
+		{
+			name: "Should return false",
+			configData: starboard.ConfigData{
+				"foo": "bar",
+			},
+			expectedOutput: false,
+		},
+		{
+			name: "Should return true",
+			configData: starboard.ConfigData{
+				"foo": "bar",
+				"trivy.ignoreFile": `# Accept the risk
+CVE-2018-14618
+
+# No impact in our settings
+CVE-2019-1543`,
+			},
+			expectedOutput: true,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			exists := tc.configData.TrivyIgnoreFileExists()
+			assert.Equal(t, tc.expectedOutput, exists)
+		})
+	}
+}