chore: bump trivy-checks to v2 (#9875)

Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
This commit is contained in:
Nikita Pivkin
2026-01-30 14:02:58 +06:00
committed by GitHub
parent f00f8de637
commit ba9feb66bf
34 changed files with 568 additions and 877 deletions

View File

@@ -16,7 +16,7 @@ trivy config [flags] DIR
--cache-ttl duration cache TTL when using redis as cache backend
--cf-params strings specify paths to override the CloudFormation parameters files
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--compliance string compliance report to generate
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
--config-data strings specify paths from which data for the Rego checks will be recursively loaded

View File

@@ -26,7 +26,7 @@ trivy filesystem [flags] PATH
--cache-ttl duration cache TTL when using redis as cache backend
--cf-params strings specify paths to override the CloudFormation parameters files
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--compliance string compliance report to generate
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
--config-data strings specify paths from which data for the Rego checks will be recursively loaded

View File

@@ -40,7 +40,7 @@ trivy image [flags] IMAGE_NAME
--cache-backend string [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--compliance string compliance report to generate (built-in compliance's: docker-cis-1.6.0)
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
--config-data strings specify paths from which data for the Rego checks will be recursively loaded

View File

@@ -36,7 +36,7 @@ trivy kubernetes [flags] [CONTEXT]
--cache-backend string [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--compliance string compliance report to generate
Built-in compliance's:
- k8s-nsa-1.0

View File

@@ -26,7 +26,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--cache-ttl duration cache TTL when using redis as cache backend
--cf-params strings specify paths to override the CloudFormation parameters files
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--commit string pass the commit hash to be scanned
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
--config-data strings specify paths from which data for the Rego checks will be recursively loaded

View File

@@ -29,7 +29,7 @@ trivy rootfs [flags] ROOTDIR
--cache-ttl duration cache TTL when using redis as cache backend
--cf-params strings specify paths to override the CloudFormation parameters files
--check-namespaces strings Rego namespaces
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
--config-file-schemas strings specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking

View File

@@ -26,7 +26,7 @@ trivy vm [flags] VM_IMAGE
--aws-region string AWS region to scan
--cache-backend string [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:2")
--compliance string compliance report to generate
--config-file-schemas strings specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
--custom-headers strings custom headers in client mode

View File

@@ -392,7 +392,7 @@ ansible:
misconfiguration:
# Same as '--checks-bundle-repository'
checks-bundle-repository: "mirror.gcr.io/aquasec/trivy-checks:1"
checks-bundle-repository: "mirror.gcr.io/aquasec/trivy-checks:2"
cloudformation:
# Same as '--cf-params'

6
go.mod
View File

@@ -23,7 +23,7 @@ require (
github.com/aquasecurity/table v1.11.0
github.com/aquasecurity/testdocker v0.0.0-20250616060700-ba6845ac6d17
github.com/aquasecurity/tml v0.6.1
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169
github.com/aquasecurity/trivy-checks v1.12.2-0.20251219190323-79d27547baf5
github.com/aquasecurity/trivy-db v0.0.0-20251222105351-a833f47f8f0d
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
github.com/aquasecurity/trivy-kubernetes v0.9.1
@@ -378,7 +378,7 @@ require (
github.com/oklog/ulid/v2 v2.1.1 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect
github.com/opencontainers/selinux v1.13.0 // indirect
github.com/owenrumney/squealer v1.2.11 // indirect
github.com/owenrumney/squealer v1.2.12 // indirect
github.com/pandatix/go-cvss v0.6.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
@@ -502,7 +502,7 @@ require (
modernc.org/libc v1.66.10 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
mvdan.cc/sh/v3 v3.11.0 // indirect
mvdan.cc/sh/v3 v3.12.0 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
pluginrpc.com/pluginrpc v0.5.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect

12
go.sum
View File

@@ -173,8 +173,8 @@ github.com/aquasecurity/testdocker v0.0.0-20250616060700-ba6845ac6d17 h1:/xWTD1Y
github.com/aquasecurity/testdocker v0.0.0-20250616060700-ba6845ac6d17/go.mod h1:6kYuX29QyBWHJejvbKkA4yzz8EUX/Fn+GmQ09JAZ5lY=
github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo=
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169 h1:TckzIxUX7lZaU9f2lNxCN0noYYP8fzmSQf6a4JdV83w=
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169/go.mod h1:nT69xgRcBD4NlHwTBpWMYirpK5/Zpl8M+XDOgmjMn2k=
github.com/aquasecurity/trivy-checks v1.12.2-0.20251219190323-79d27547baf5 h1:8HnXyjgCiJwVX1mTKeqdyizd7ZBmXMPL+BMQ5UZd0Nk=
github.com/aquasecurity/trivy-checks v1.12.2-0.20251219190323-79d27547baf5/go.mod h1:hBSA3ziBFwGENK6/PYNIKm6N24SFg0wsv1VXeqPG/3M=
github.com/aquasecurity/trivy-db v0.0.0-20251222105351-a833f47f8f0d h1:mwCxwhDRnW5UkSQdZfekTCjaLyWp1rqfIa6KKRdMDAo=
github.com/aquasecurity/trivy-db v0.0.0-20251222105351-a833f47f8f0d/go.mod h1:B0cbg/BEHbJg2RcS7PLdlbGCzz2TkChcZAiI4oSs0VI=
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
@@ -936,8 +936,8 @@ github.com/openvex/go-vex v0.2.7/go.mod h1:ZyQC3NXl9jjS53JOpBG3LAUXySkW8IlJ/GIhs
github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U=
github.com/owenrumney/go-sarif/v2 v2.3.3 h1:ubWDJcF5i3L/EIOER+ZyQ03IfplbSU1BLOE26uKQIIU=
github.com/owenrumney/go-sarif/v2 v2.3.3/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
github.com/owenrumney/squealer v1.2.11 h1:vMudrj70VeOzY+t7Phz9Yo0wAgm4kXes9DcTLBVDqGY=
github.com/owenrumney/squealer v1.2.11/go.mod h1:8KOuitfOfmS/OtzgxQbxnnrbngAGopfgKB/BiGGpqGA=
github.com/owenrumney/squealer v1.2.12 h1:6VQxQ323q7q0eKNP5p7MX4nbTW1z8wK44YvyHLwDcx0=
github.com/owenrumney/squealer v1.2.12/go.mod h1:yBdddxW+31mPHXgjOAYiqCtK1/f1S3o5Jq6S6vZGtxc=
github.com/package-url/packageurl-go v0.1.3 h1:4juMED3hHiz0set3Vq3KeQ75KD1avthoXLtmE3I0PLs=
github.com/package-url/packageurl-go v0.1.3/go.mod h1:nKAWB8E6uk1MHqiS/lQb9pYBGH2+mdJ2PJc2s50dQY0=
github.com/pandatix/go-cvss v0.6.2 h1:TFiHlzUkT67s6UkelHmK6s1INKVUG7nlKYiWWDTITGI=
@@ -1545,8 +1545,8 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
mvdan.cc/sh/v3 v3.11.0 h1:q5h+XMDRfUGUedCqFFsjoFjrhwf2Mvtt1rkMvVz0blw=
mvdan.cc/sh/v3 v3.11.0/go.mod h1:LRM+1NjoYCzuq/WZ6y44x14YNAI0NK7FLPeQSaFagGg=
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg=
oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc=
oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o=
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=

View File

@@ -19,8 +19,7 @@
"Misconfigurations": [
{
"Type": "Dockerfile Security Check",
"ID": "DS002",
"AVDID": "AVD-DS-0002",
"ID": "DS-0002",
"Title": "Image user should not be 'root'",
"Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",
"Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument",
@@ -28,10 +27,10 @@
"Query": "data.builtin.dockerfile.DS002.deny",
"Resolution": "Add 'USER \u003cnon root user name\u003e' line to the Dockerfile",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds002",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds-0002",
"References": [
"https://docs.docker.com/develop/develop-images/dockerfile_best-practices/",
"https://avd.aquasec.com/misconfig/ds002"
"https://avd.aquasec.com/misconfig/ds-0002"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -19,8 +19,7 @@
"Misconfigurations": [
{
"Type": "Dockerfile Security Check",
"ID": "DS002",
"AVDID": "AVD-DS-0002",
"ID": "DS-0002",
"Title": "Image user should not be 'root'",
"Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",
"Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument",
@@ -28,10 +27,10 @@
"Query": "data.builtin.dockerfile.DS002.deny",
"Resolution": "Add 'USER \u003cnon root user name\u003e' line to the Dockerfile",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds002",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds-0002",
"References": [
"https://docs.docker.com/develop/develop-images/dockerfile_best-practices/",
"https://avd.aquasec.com/misconfig/ds002"
"https://avd.aquasec.com/misconfig/ds-0002"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,14 +13,13 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 78,
"Successes": 81,
"Failures": 18
},
"Misconfigurations": [
{
"Type": "Helm Security Check",
"ID": "KSV001",
"AVDID": "AVD-KSV-0001",
"ID": "KSV-0001",
"Title": "Can elevate its own privileges",
"Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.allowPrivilegeEscalation' to false",
@@ -28,10 +27,10 @@
"Query": "data.builtin.kubernetes.KSV001.deny",
"Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv001",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0001",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv001"
"https://avd.aquasec.com/misconfig/ksv-0001"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -87,8 +86,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV003",
"AVDID": "AVD-KSV-0003",
"ID": "KSV-0003",
"Title": "Default capabilities: some containers do not drop all",
"Description": "The container should drop all default capabilities and add only those that are needed for its execution.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should add 'ALL' to 'securityContext.capabilities.drop'",
@@ -96,10 +94,10 @@
"Query": "data.builtin.kubernetes.KSV003.deny",
"Resolution": "Add 'ALL' to containers[].securityContext.capabilities.drop.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv003",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0003",
"References": [
"https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/",
"https://avd.aquasec.com/misconfig/ksv003"
"https://avd.aquasec.com/misconfig/ksv-0003"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -155,8 +153,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV004",
"AVDID": "AVD-KSV-0004",
"ID": "KSV-0004",
"Title": "Default capabilities: some containers do not drop any",
"Description": "Security best practices require containers to run with minimal required capabilities.",
"Message": "Container 'nginx' of 'deployment' 'nginx-deployment' in 'default' namespace should set securityContext.capabilities.drop",
@@ -164,10 +161,10 @@
"Query": "data.builtin.kubernetes.KSV004.deny",
"Resolution": "Specify at least one unneeded capability in 'containers[].securityContext.capabilities.drop'",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv004",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0004",
"References": [
"https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/",
"https://avd.aquasec.com/misconfig/ksv004"
"https://avd.aquasec.com/misconfig/ksv-0004"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -223,8 +220,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV011",
"AVDID": "AVD-KSV-0011",
"ID": "KSV-0011",
"Title": "CPU not limited",
"Description": "Enforcing CPU limits prevents DoS via resource exhaustion.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.limits.cpu'",
@@ -232,10 +228,10 @@
"Query": "data.builtin.kubernetes.KSV011.deny",
"Resolution": "Set a limit value under 'containers[].resources.limits.cpu'.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv011",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0011",
"References": [
"https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits",
"https://avd.aquasec.com/misconfig/ksv011"
"https://avd.aquasec.com/misconfig/ksv-0011"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -291,8 +287,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV012",
"AVDID": "AVD-KSV-0012",
"ID": "KSV-0012",
"Title": "Runs as root user",
"Description": "Force the running image to run as a non-root user to ensure least privileges.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsNonRoot' to true",
@@ -300,10 +295,10 @@
"Query": "data.builtin.kubernetes.KSV012.deny",
"Resolution": "Set 'containers[].securityContext.runAsNonRoot' to true.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv012",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0012",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv012"
"https://avd.aquasec.com/misconfig/ksv-0012"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -359,8 +354,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV014",
"AVDID": "AVD-KSV-0014",
"ID": "KSV-0014",
"Title": "Root file system is not read-only",
"Description": "An immutable root file system prevents applications from writing to their local disk. This can limit intrusions, as attackers will not be able to tamper with the file system or write foreign executables to disk.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.readOnlyRootFilesystem' to true",
@@ -368,10 +362,10 @@
"Query": "data.builtin.kubernetes.KSV014.deny",
"Resolution": "Change 'containers[].securityContext.readOnlyRootFilesystem' to 'true'.",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv014",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0014",
"References": [
"https://kubesec.io/basics/containers-securitycontext-readonlyrootfilesystem-true/",
"https://avd.aquasec.com/misconfig/ksv014"
"https://avd.aquasec.com/misconfig/ksv-0014"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -427,8 +421,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV015",
"AVDID": "AVD-KSV-0015",
"ID": "KSV-0015",
"Title": "CPU requests not specified",
"Description": "When containers have resource requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.requests.cpu'",
@@ -436,10 +429,10 @@
"Query": "data.builtin.kubernetes.KSV015.deny",
"Resolution": "Set 'containers[].resources.requests.cpu'.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv015",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0015",
"References": [
"https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits",
"https://avd.aquasec.com/misconfig/ksv015"
"https://avd.aquasec.com/misconfig/ksv-0015"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -495,8 +488,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV016",
"AVDID": "AVD-KSV-0016",
"ID": "KSV-0016",
"Title": "Memory requests not specified",
"Description": "When containers have memory requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.requests.memory'",
@@ -504,10 +496,10 @@
"Query": "data.builtin.kubernetes.KSV016.deny",
"Resolution": "Set 'containers[].resources.requests.memory'.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv016",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0016",
"References": [
"https://kubesec.io/basics/containers-resources-limits-memory/",
"https://avd.aquasec.com/misconfig/ksv016"
"https://avd.aquasec.com/misconfig/ksv-0016"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -563,8 +555,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV018",
"AVDID": "AVD-KSV-0018",
"ID": "KSV-0018",
"Title": "Memory not limited",
"Description": "Enforcing memory limits prevents DoS via resource exhaustion.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.limits.memory'",
@@ -572,10 +563,10 @@
"Query": "data.builtin.kubernetes.KSV018.deny",
"Resolution": "Set a limit value under 'containers[].resources.limits.memory'.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv018",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0018",
"References": [
"https://kubesec.io/basics/containers-resources-limits-memory/",
"https://avd.aquasec.com/misconfig/ksv018"
"https://avd.aquasec.com/misconfig/ksv-0018"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -631,8 +622,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV020",
"AVDID": "AVD-KSV-0020",
"ID": "KSV-0020",
"Title": "Runs with UID \u003c= 10000",
"Description": "Force the container to run with user ID \u003e 10000 to avoid conflicts with the hosts user table.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsUser' \u003e 10000",
@@ -640,10 +630,10 @@
"Query": "data.builtin.kubernetes.KSV020.deny",
"Resolution": "Set 'containers[].securityContext.runAsUser' to an integer \u003e 10000.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv020",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0020",
"References": [
"https://kubesec.io/basics/containers-securitycontext-runasuser/",
"https://avd.aquasec.com/misconfig/ksv020"
"https://avd.aquasec.com/misconfig/ksv-0020"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -699,8 +689,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV021",
"AVDID": "AVD-KSV-0021",
"ID": "KSV-0021",
"Title": "Runs with GID \u003c= 10000",
"Description": "Force the container to run with group ID \u003e 10000 to avoid conflicts with the hosts user table.",
"Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsGroup' \u003e 10000",
@@ -708,10 +697,10 @@
"Query": "data.builtin.kubernetes.KSV021.deny",
"Resolution": "Set 'containers[].securityContext.runAsGroup' to an integer \u003e 10000.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv021",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0021",
"References": [
"https://kubesec.io/basics/containers-securitycontext-runasuser/",
"https://avd.aquasec.com/misconfig/ksv021"
"https://avd.aquasec.com/misconfig/ksv-0021"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -767,8 +756,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV030",
"AVDID": "AVD-KSV-0030",
"ID": "KSV-0030",
"Title": "Runtime/Default Seccomp profile not set",
"Description": "According to pod security standard 'Seccomp', the RuntimeDefault seccomp profile must be required, or allow specific additional profiles.",
"Message": "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'",
@@ -776,10 +764,10 @@
"Query": "data.builtin.kubernetes.KSV030.deny",
"Resolution": "Set 'spec.securityContext.seccompProfile.type', 'spec.containers[*].securityContext.seccompProfile' and 'spec.initContainers[*].securityContext.seccompProfile' to 'RuntimeDefault' or undefined.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv030",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0030",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv030"
"https://avd.aquasec.com/misconfig/ksv-0030"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -835,8 +823,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV104",
"AVDID": "AVD-KSV-0104",
"ID": "KSV-0104",
"Title": "Seccomp policies disabled",
"Description": "A program inside the container can bypass Seccomp protection policies.",
"Message": "container \"nginx\" of deployment \"nginx-deployment\" in \"default\" namespace should specify a seccomp profile",
@@ -844,10 +831,10 @@
"Query": "data.builtin.kubernetes.KSV104.deny",
"Resolution": "Specify seccomp either by annotation or by seccomp profile type having allowed values as per pod security standards",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv104",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0104",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline",
"https://avd.aquasec.com/misconfig/ksv104"
"https://avd.aquasec.com/misconfig/ksv-0104"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -903,8 +890,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV106",
"AVDID": "AVD-KSV-0106",
"ID": "KSV-0106",
"Title": "Container capabilities must only include NET_BIND_SERVICE",
"Description": "Containers must drop ALL capabilities, and are only permitted to add back the NET_BIND_SERVICE capability.",
"Message": "container should drop all",
@@ -912,10 +898,10 @@
"Query": "data.builtin.kubernetes.KSV106.deny",
"Resolution": "Set 'spec.containers[*].securityContext.capabilities.drop' to 'ALL' and only add 'NET_BIND_SERVICE' to 'spec.containers[*].securityContext.capabilities.add'.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv106",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0106",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv106"
"https://avd.aquasec.com/misconfig/ksv-0106"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -971,8 +957,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV110",
"AVDID": "AVD-KSV-0110",
"ID": "KSV-0110",
"Title": "Workloads in the default namespace",
"Description": "Checks whether a workload is running in the default namespace.",
"Message": "deployment nginx-deployment in default namespace should set metadata.namespace to a non-default namespace",
@@ -980,10 +965,10 @@
"Query": "data.builtin.kubernetes.KSV110.deny",
"Resolution": "Set 'metadata.namespace' to a non-default namespace.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv110",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0110",
"References": [
"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/",
"https://avd.aquasec.com/misconfig/ksv110"
"https://avd.aquasec.com/misconfig/ksv-0110"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -1039,8 +1024,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV117",
"AVDID": "AVD-KSV-0117",
"ID": "KSV-0117",
"Title": "Prevent binding to privileged ports",
"Description": "The ports which are lower than 1024 receive and transmit various sensitive and privileged data. Allowing containers to use them can bring serious implications.",
"Message": "deployment nginx-deployment in default namespace should not set spec.template.spec.containers.ports.containerPort to less than 1024",
@@ -1048,11 +1032,11 @@
"Query": "data.builtin.kubernetes.KSV117.deny",
"Resolution": "Do not map the container ports to privileged host ports when starting a container.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv117",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0117",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"https://www.stigviewer.com/stig/kubernetes/2022-12-02/finding/V-242414",
"https://avd.aquasec.com/misconfig/ksv117"
"https://avd.aquasec.com/misconfig/ksv-0117"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -1062,8 +1046,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV118",
"AVDID": "AVD-KSV-0118",
"ID": "KSV-0118",
"Title": "Default security context configured",
"Description": "Security context controls the allocation of security parameters for the pod/container/volume, ensuring the appropriate level of protection. Relying on default security context may expose vulnerabilities to potential attacks that rely on privileged access.",
"Message": "container nginx-deployment in default namespace is using the default security context",
@@ -1071,10 +1054,10 @@
"Query": "data.builtin.kubernetes.KSV118.deny",
"Resolution": "To enhance security, it is strongly recommended not to rely on the default security context. Instead, it is advisable to explicitly define the required security parameters (such as runAsNonRoot, capabilities, readOnlyRootFilesystem, etc.) within the security context.",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv118",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0118",
"References": [
"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",
"https://avd.aquasec.com/misconfig/ksv118"
"https://avd.aquasec.com/misconfig/ksv-0118"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -1130,8 +1113,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV118",
"AVDID": "AVD-KSV-0118",
"ID": "KSV-0118",
"Title": "Default security context configured",
"Description": "Security context controls the allocation of security parameters for the pod/container/volume, ensuring the appropriate level of protection. Relying on default security context may expose vulnerabilities to potential attacks that rely on privileged access.",
"Message": "deployment nginx-deployment in default namespace is using the default security context, which allows root privileges",
@@ -1139,10 +1121,10 @@
"Query": "data.builtin.kubernetes.KSV118.deny",
"Resolution": "To enhance security, it is strongly recommended not to rely on the default security context. Instead, it is advisable to explicitly define the required security parameters (such as runAsNonRoot, capabilities, readOnlyRootFilesystem, etc.) within the security context.",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv118",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0118",
"References": [
"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",
"https://avd.aquasec.com/misconfig/ksv118"
"https://avd.aquasec.com/misconfig/ksv-0118"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,14 +13,13 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 89,
"Successes": 92,
"Failures": 6
},
"Misconfigurations": [
{
"Type": "Helm Security Check",
"ID": "KSV001",
"AVDID": "AVD-KSV-0001",
"ID": "KSV-0001",
"Title": "Can elevate its own privileges",
"Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.",
"Message": "Container 'testchart' of Deployment 'testchart' should set 'securityContext.allowPrivilegeEscalation' to false",
@@ -28,10 +27,10 @@
"Query": "data.builtin.kubernetes.KSV001.deny",
"Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv001",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0001",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv001"
"https://avd.aquasec.com/misconfig/ksv-0001"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -146,8 +145,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV030",
"AVDID": "AVD-KSV-0030",
"ID": "KSV-0030",
"Title": "Runtime/Default Seccomp profile not set",
"Description": "According to pod security standard 'Seccomp', the RuntimeDefault seccomp profile must be required, or allow specific additional profiles.",
"Message": "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'",
@@ -155,10 +153,10 @@
"Query": "data.builtin.kubernetes.KSV030.deny",
"Resolution": "Set 'spec.securityContext.seccompProfile.type', 'spec.containers[*].securityContext.seccompProfile' and 'spec.initContainers[*].securityContext.seccompProfile' to 'RuntimeDefault' or undefined.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv030",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0030",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv030"
"https://avd.aquasec.com/misconfig/ksv-0030"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -273,8 +271,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV104",
"AVDID": "AVD-KSV-0104",
"ID": "KSV-0104",
"Title": "Seccomp policies disabled",
"Description": "A program inside the container can bypass Seccomp protection policies.",
"Message": "container \"testchart\" of deployment \"testchart\" in \"default\" namespace should specify a seccomp profile",
@@ -282,10 +279,10 @@
"Query": "data.builtin.kubernetes.KSV104.deny",
"Resolution": "Specify seccomp either by annotation or by seccomp profile type having allowed values as per pod security standards",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv104",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0104",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline",
"https://avd.aquasec.com/misconfig/ksv104"
"https://avd.aquasec.com/misconfig/ksv-0104"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -400,8 +397,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV110",
"AVDID": "AVD-KSV-0110",
"ID": "KSV-0110",
"Title": "Workloads in the default namespace",
"Description": "Checks whether a workload is running in the default namespace.",
"Message": "deployment testchart in default namespace should set metadata.namespace to a non-default namespace",
@@ -409,10 +405,10 @@
"Query": "data.builtin.kubernetes.KSV110.deny",
"Resolution": "Set 'metadata.namespace' to a non-default namespace.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv110",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0110",
"References": [
"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/",
"https://avd.aquasec.com/misconfig/ksv110"
"https://avd.aquasec.com/misconfig/ksv-0110"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -508,8 +504,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV117",
"AVDID": "AVD-KSV-0117",
"ID": "KSV-0117",
"Title": "Prevent binding to privileged ports",
"Description": "The ports which are lower than 1024 receive and transmit various sensitive and privileged data. Allowing containers to use them can bring serious implications.",
"Message": "deployment testchart in default namespace should not set spec.template.spec.containers.ports.containerPort to less than 1024",
@@ -517,11 +512,11 @@
"Query": "data.builtin.kubernetes.KSV117.deny",
"Resolution": "Do not map the container ports to privileged host ports when starting a container.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv117",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0117",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"https://www.stigviewer.com/stig/kubernetes/2022-12-02/finding/V-242414",
"https://avd.aquasec.com/misconfig/ksv117"
"https://avd.aquasec.com/misconfig/ksv-0117"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -531,8 +526,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV118",
"AVDID": "AVD-KSV-0118",
"ID": "KSV-0118",
"Title": "Default security context configured",
"Description": "Security context controls the allocation of security parameters for the pod/container/volume, ensuring the appropriate level of protection. Relying on default security context may expose vulnerabilities to potential attacks that rely on privileged access.",
"Message": "deployment testchart in default namespace is using the default security context, which allows root privileges",
@@ -540,10 +534,10 @@
"Query": "data.builtin.kubernetes.KSV118.deny",
"Resolution": "To enhance security, it is strongly recommended not to rely on the default security context. Instead, it is advisable to explicitly define the required security parameters (such as runAsNonRoot, capabilities, readOnlyRootFilesystem, etc.) within the security context.",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv118",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0118",
"References": [
"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",
"https://avd.aquasec.com/misconfig/ksv118"
"https://avd.aquasec.com/misconfig/ksv-0118"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -663,7 +657,7 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 59,
"Successes": 62,
"Failures": 0
}
},
@@ -672,7 +666,7 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 58,
"Successes": 61,
"Failures": 0
}
}

View File

@@ -13,14 +13,13 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 87,
"Successes": 90,
"Failures": 8
},
"Misconfigurations": [
{
"Type": "Helm Security Check",
"ID": "KSV001",
"AVDID": "AVD-KSV-0001",
"ID": "KSV-0001",
"Title": "Can elevate its own privileges",
"Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.",
"Message": "Container 'testchart' of Deployment 'testchart' should set 'securityContext.allowPrivilegeEscalation' to false",
@@ -28,10 +27,10 @@
"Query": "data.builtin.kubernetes.KSV001.deny",
"Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv001",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0001",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv001"
"https://avd.aquasec.com/misconfig/ksv-0001"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -146,8 +145,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV020",
"AVDID": "AVD-KSV-0020",
"ID": "KSV-0020",
"Title": "Runs with UID \u003c= 10000",
"Description": "Force the container to run with user ID \u003e 10000 to avoid conflicts with the hosts user table.",
"Message": "Container 'testchart' of Deployment 'testchart' should set 'securityContext.runAsUser' \u003e 10000",
@@ -155,10 +153,10 @@
"Query": "data.builtin.kubernetes.KSV020.deny",
"Resolution": "Set 'containers[].securityContext.runAsUser' to an integer \u003e 10000.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv020",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0020",
"References": [
"https://kubesec.io/basics/containers-securitycontext-runasuser/",
"https://avd.aquasec.com/misconfig/ksv020"
"https://avd.aquasec.com/misconfig/ksv-0020"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -273,8 +271,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV030",
"AVDID": "AVD-KSV-0030",
"ID": "KSV-0030",
"Title": "Runtime/Default Seccomp profile not set",
"Description": "According to pod security standard 'Seccomp', the RuntimeDefault seccomp profile must be required, or allow specific additional profiles.",
"Message": "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'",
@@ -282,10 +279,10 @@
"Query": "data.builtin.kubernetes.KSV030.deny",
"Resolution": "Set 'spec.securityContext.seccompProfile.type', 'spec.containers[*].securityContext.seccompProfile' and 'spec.initContainers[*].securityContext.seccompProfile' to 'RuntimeDefault' or undefined.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv030",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0030",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv030"
"https://avd.aquasec.com/misconfig/ksv-0030"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -400,8 +397,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV104",
"AVDID": "AVD-KSV-0104",
"ID": "KSV-0104",
"Title": "Seccomp policies disabled",
"Description": "A program inside the container can bypass Seccomp protection policies.",
"Message": "container \"testchart\" of deployment \"testchart\" in \"default\" namespace should specify a seccomp profile",
@@ -409,10 +405,10 @@
"Query": "data.builtin.kubernetes.KSV104.deny",
"Resolution": "Specify seccomp either by annotation or by seccomp profile type having allowed values as per pod security standards",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv104",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0104",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline",
"https://avd.aquasec.com/misconfig/ksv104"
"https://avd.aquasec.com/misconfig/ksv-0104"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -527,8 +523,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV105",
"AVDID": "AVD-KSV-0105",
"ID": "KSV-0105",
"Title": "Containers must not set runAsUser to 0",
"Description": "Containers should be forbidden from running with a root UID.",
"Message": "securityContext.runAsUser should be set to a value greater than 0",
@@ -536,10 +531,10 @@
"Query": "data.builtin.kubernetes.KSV105.deny",
"Resolution": "Set 'securityContext.runAsUser' to a non-zero integer or leave undefined.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv105",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0105",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
"https://avd.aquasec.com/misconfig/ksv105"
"https://avd.aquasec.com/misconfig/ksv-0105"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -635,8 +630,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV110",
"AVDID": "AVD-KSV-0110",
"ID": "KSV-0110",
"Title": "Workloads in the default namespace",
"Description": "Checks whether a workload is running in the default namespace.",
"Message": "deployment testchart in default namespace should set metadata.namespace to a non-default namespace",
@@ -644,10 +638,10 @@
"Query": "data.builtin.kubernetes.KSV110.deny",
"Resolution": "Set 'metadata.namespace' to a non-default namespace.",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv110",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0110",
"References": [
"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/",
"https://avd.aquasec.com/misconfig/ksv110"
"https://avd.aquasec.com/misconfig/ksv-0110"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -743,8 +737,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV117",
"AVDID": "AVD-KSV-0117",
"ID": "KSV-0117",
"Title": "Prevent binding to privileged ports",
"Description": "The ports which are lower than 1024 receive and transmit various sensitive and privileged data. Allowing containers to use them can bring serious implications.",
"Message": "deployment testchart in default namespace should not set spec.template.spec.containers.ports.containerPort to less than 1024",
@@ -752,11 +745,11 @@
"Query": "data.builtin.kubernetes.KSV117.deny",
"Resolution": "Do not map the container ports to privileged host ports when starting a container.",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv117",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0117",
"References": [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"https://www.stigviewer.com/stig/kubernetes/2022-12-02/finding/V-242414",
"https://avd.aquasec.com/misconfig/ksv117"
"https://avd.aquasec.com/misconfig/ksv-0117"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -766,8 +759,7 @@
},
{
"Type": "Helm Security Check",
"ID": "KSV118",
"AVDID": "AVD-KSV-0118",
"ID": "KSV-0118",
"Title": "Default security context configured",
"Description": "Security context controls the allocation of security parameters for the pod/container/volume, ensuring the appropriate level of protection. Relying on default security context may expose vulnerabilities to potential attacks that rely on privileged access.",
"Message": "deployment testchart in default namespace is using the default security context, which allows root privileges",
@@ -775,10 +767,10 @@
"Query": "data.builtin.kubernetes.KSV118.deny",
"Resolution": "To enhance security, it is strongly recommended not to rely on the default security context. Instead, it is advisable to explicitly define the required security parameters (such as runAsNonRoot, capabilities, readOnlyRootFilesystem, etc.) within the security context.",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv118",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ksv-0118",
"References": [
"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",
"https://avd.aquasec.com/misconfig/ksv118"
"https://avd.aquasec.com/misconfig/ksv-0118"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -898,7 +890,7 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 59,
"Successes": 62,
"Failures": 0
}
},
@@ -907,7 +899,7 @@
"Class": "config",
"Type": "helm",
"MisconfSummary": {
"Successes": 58,
"Successes": 61,
"Failures": 0
}
}

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 45,
"Successes": 58,
"Failures": 0
}
},

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 45,
"Successes": 58,
"Failures": 0
}
},
@@ -23,149 +23,12 @@
"Type": "terraform",
"MisconfSummary": {
"Successes": 0,
"Failures": 4
"Failures": 3
},
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0088",
"AVDID": "AVD-AWS-0088",
"Title": "Unencrypted S3 bucket.",
"Description": "S3 Buckets should be encrypted to protect the data that is stored within them if access is compromised.\n",
"Message": "Bucket does not have encryption enabled",
"Namespace": "builtin.aws.s3.aws0088",
"Query": "data.builtin.aws.s3.aws0088.deny",
"Resolution": "Configure bucket encryption",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0088",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0088"
],
"Status": "FAIL",
"CauseMetadata": {
"Resource": "module.bucket",
"Provider": "AWS",
"Service": "s3",
"StartLine": 25,
"EndLine": 36,
"Code": {
"Lines": [
{
"Number": 25,
"Content": "resource \"aws_s3_bucket\" \"this\" {",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[38;5;33mresource\u001b[0m \u001b[38;5;37m\"aws_s3_bucket\"\u001b[0m \u001b[38;5;37m\"this\"\u001b[0m {",
"FirstCause": true,
"LastCause": false
},
{
"Number": 26,
"Content": " count = local.create_bucket \u0026\u0026 !var.is_directory_bucket ? 1 : 0",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mcount\u001b[0m = local.create_bucket \u001b[38;5;245m\u0026\u0026\u001b[0m \u001b[38;5;245m!\u001b[0m\u001b[38;5;33mvar\u001b[0m.is_directory_bucket \u001b[38;5;245m?\u001b[0m \u001b[38;5;37m1\u001b[0m \u001b[38;5;245m:\u001b[0m \u001b[38;5;37m0",
"FirstCause": false,
"LastCause": false
},
{
"Number": 27,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[0m",
"FirstCause": false,
"LastCause": false
},
{
"Number": 28,
"Content": " region = var.region",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mregion\u001b[0m = \u001b[38;5;33mvar\u001b[0m.region",
"FirstCause": false,
"LastCause": false
},
{
"Number": 29,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 30,
"Content": " bucket = var.bucket",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket",
"FirstCause": false,
"LastCause": false
},
{
"Number": 31,
"Content": " bucket_prefix = var.bucket_prefix",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket_prefix\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket_prefix",
"FirstCause": false,
"LastCause": false
},
{
"Number": 32,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 33,
"Content": " force_destroy = var.force_destroy",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mforce_destroy\u001b[0m = \u001b[38;5;33mvar\u001b[0m.force_destroy",
"FirstCause": false,
"LastCause": true
},
{
"Number": 34,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": true,
"FirstCause": false,
"LastCause": false
}
]
},
"Occurrences": [
{
"Resource": "module.bucket",
"Filename": "main.tf",
"Location": {
"StartLine": 1,
"EndLine": 5
}
}
]
}
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0089",
"AVDID": "AVD-AWS-0089",
"ID": "AWS-0089",
"Title": "S3 Bucket Logging",
"Description": "Ensures S3 bucket logging is enabled for S3 buckets",
"Message": "Bucket has logging disabled",
@@ -173,11 +36,11 @@
"Query": "data.builtin.aws.s3.aws0089.deny",
"Resolution": "Add a logging block to the resource to enable access logging",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0089",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0089",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html",
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html",
"https://avd.aquasec.com/misconfig/avd-aws-0089"
"https://avd.aquasec.com/misconfig/aws-0089"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -301,8 +164,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0090",
"AVDID": "AVD-AWS-0090",
"ID": "AWS-0090",
"Title": "S3 Data should be versioned",
"Description": "Versioning in Amazon S3 is a means of keeping multiple variants of an object in the same bucket.\n\nYou can use the S3 Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets.\n\nWith versioning you can recover more easily from both unintended user actions and application failures.\n\nWhen you enable versioning, also keep in mind the potential costs of storing noncurrent versions of objects. To help manage those costs, consider setting up an S3 Lifecycle configuration.\n",
"Message": "Bucket does not have versioning enabled",
@@ -310,11 +172,11 @@
"Query": "data.builtin.aws.s3.aws0090.deny",
"Resolution": "Enable versioning to protect against accidental/malicious removal or modification",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0090",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0090",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html",
"https://aws.amazon.com/blogs/storage/reduce-storage-costs-with-fewer-noncurrent-versions-using-amazon-s3-lifecycle/",
"https://avd.aquasec.com/misconfig/avd-aws-0090"
"https://avd.aquasec.com/misconfig/aws-0090"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -438,8 +300,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0132",
"AVDID": "AVD-AWS-0132",
"ID": "AWS-0132",
"Title": "S3 encryption should use Customer Managed Keys",
"Description": "Encryption using AWS keys provides protection for your S3 buckets. To gain greater control over encryption, such as key rotation, access policies, and auditability, use customer managed keys (CMKs) with SSE-KMS.\nNote that SSE-KMS is not supported for S3 server access logging destination buckets; in such cases, use SSE-S3 instead.\n",
"Message": "Bucket does not encrypt data with a customer managed key.",
@@ -447,10 +308,10 @@
"Query": "data.builtin.aws.s3.aws0132.deny",
"Resolution": "Use SSE-KMS with a customer managed key (CMK)",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0132",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0132",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0132"
"https://avd.aquasec.com/misconfig/aws-0132"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 45,
"Successes": 58,
"Failures": 0
}
},
@@ -23,157 +23,12 @@
"Type": "terraform",
"MisconfSummary": {
"Successes": 0,
"Failures": 4
"Failures": 3
},
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0088",
"AVDID": "AVD-AWS-0088",
"Title": "Unencrypted S3 bucket.",
"Description": "S3 Buckets should be encrypted to protect the data that is stored within them if access is compromised.\n",
"Message": "Bucket does not have encryption enabled",
"Namespace": "builtin.aws.s3.aws0088",
"Query": "data.builtin.aws.s3.aws0088.deny",
"Resolution": "Configure bucket encryption",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0088",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0088"
],
"Status": "FAIL",
"CauseMetadata": {
"Resource": "module.this",
"Provider": "AWS",
"Service": "s3",
"StartLine": 25,
"EndLine": 36,
"Code": {
"Lines": [
{
"Number": 25,
"Content": "resource \"aws_s3_bucket\" \"this\" {",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[38;5;33mresource\u001b[0m \u001b[38;5;37m\"aws_s3_bucket\"\u001b[0m \u001b[38;5;37m\"this\"\u001b[0m {",
"FirstCause": true,
"LastCause": false
},
{
"Number": 26,
"Content": " count = local.create_bucket \u0026\u0026 !var.is_directory_bucket ? 1 : 0",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mcount\u001b[0m = local.create_bucket \u001b[38;5;245m\u0026\u0026\u001b[0m \u001b[38;5;245m!\u001b[0m\u001b[38;5;33mvar\u001b[0m.is_directory_bucket \u001b[38;5;245m?\u001b[0m \u001b[38;5;37m1\u001b[0m \u001b[38;5;245m:\u001b[0m \u001b[38;5;37m0",
"FirstCause": false,
"LastCause": false
},
{
"Number": 27,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[0m",
"FirstCause": false,
"LastCause": false
},
{
"Number": 28,
"Content": " region = var.region",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mregion\u001b[0m = \u001b[38;5;33mvar\u001b[0m.region",
"FirstCause": false,
"LastCause": false
},
{
"Number": 29,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 30,
"Content": " bucket = var.bucket",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket",
"FirstCause": false,
"LastCause": false
},
{
"Number": 31,
"Content": " bucket_prefix = var.bucket_prefix",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket_prefix\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket_prefix",
"FirstCause": false,
"LastCause": false
},
{
"Number": 32,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 33,
"Content": " force_destroy = var.force_destroy",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mforce_destroy\u001b[0m = \u001b[38;5;33mvar\u001b[0m.force_destroy",
"FirstCause": false,
"LastCause": true
},
{
"Number": 34,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": true,
"FirstCause": false,
"LastCause": false
}
]
},
"Occurrences": [
{
"Resource": "module.bucket",
"Filename": "modules/s3/main.tf",
"Location": {
"StartLine": 5,
"EndLine": 8
}
},
{
"Resource": "module.this",
"Filename": "main.tf",
"Location": {
"StartLine": 1,
"EndLine": 4
}
}
]
}
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0089",
"AVDID": "AVD-AWS-0089",
"ID": "AWS-0089",
"Title": "S3 Bucket Logging",
"Description": "Ensures S3 bucket logging is enabled for S3 buckets",
"Message": "Bucket has logging disabled",
@@ -181,11 +36,11 @@
"Query": "data.builtin.aws.s3.aws0089.deny",
"Resolution": "Add a logging block to the resource to enable access logging",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0089",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0089",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html",
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html",
"https://avd.aquasec.com/misconfig/avd-aws-0089"
"https://avd.aquasec.com/misconfig/aws-0089"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -317,8 +172,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0090",
"AVDID": "AVD-AWS-0090",
"ID": "AWS-0090",
"Title": "S3 Data should be versioned",
"Description": "Versioning in Amazon S3 is a means of keeping multiple variants of an object in the same bucket.\n\nYou can use the S3 Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets.\n\nWith versioning you can recover more easily from both unintended user actions and application failures.\n\nWhen you enable versioning, also keep in mind the potential costs of storing noncurrent versions of objects. To help manage those costs, consider setting up an S3 Lifecycle configuration.\n",
"Message": "Bucket does not have versioning enabled",
@@ -326,11 +180,11 @@
"Query": "data.builtin.aws.s3.aws0090.deny",
"Resolution": "Enable versioning to protect against accidental/malicious removal or modification",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0090",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0090",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html",
"https://aws.amazon.com/blogs/storage/reduce-storage-costs-with-fewer-noncurrent-versions-using-amazon-s3-lifecycle/",
"https://avd.aquasec.com/misconfig/avd-aws-0090"
"https://avd.aquasec.com/misconfig/aws-0090"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -462,8 +316,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0132",
"AVDID": "AVD-AWS-0132",
"ID": "AWS-0132",
"Title": "S3 encryption should use Customer Managed Keys",
"Description": "Encryption using AWS keys provides protection for your S3 buckets. To gain greater control over encryption, such as key rotation, access policies, and auditability, use customer managed keys (CMKs) with SSE-KMS.\nNote that SSE-KMS is not supported for S3 server access logging destination buckets; in such cases, use SSE-S3 instead.\n",
"Message": "Bucket does not encrypt data with a customer managed key.",
@@ -471,10 +324,10 @@
"Query": "data.builtin.aws.s3.aws0132.deny",
"Resolution": "Use SSE-KMS with a customer managed key (CMK)",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0132",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0132",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0132"
"https://avd.aquasec.com/misconfig/aws-0132"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 45,
"Successes": 58,
"Failures": 0
}
},
@@ -23,149 +23,12 @@
"Type": "terraform",
"MisconfSummary": {
"Successes": 0,
"Failures": 4
"Failures": 3
},
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0088",
"AVDID": "AVD-AWS-0088",
"Title": "Unencrypted S3 bucket.",
"Description": "S3 Buckets should be encrypted to protect the data that is stored within them if access is compromised.\n",
"Message": "Bucket does not have encryption enabled",
"Namespace": "builtin.aws.s3.aws0088",
"Query": "data.builtin.aws.s3.aws0088.deny",
"Resolution": "Configure bucket encryption",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0088",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0088"
],
"Status": "FAIL",
"CauseMetadata": {
"Resource": "module.bucket",
"Provider": "AWS",
"Service": "s3",
"StartLine": 25,
"EndLine": 36,
"Code": {
"Lines": [
{
"Number": 25,
"Content": "resource \"aws_s3_bucket\" \"this\" {",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[38;5;33mresource\u001b[0m \u001b[38;5;37m\"aws_s3_bucket\"\u001b[0m \u001b[38;5;37m\"this\"\u001b[0m {",
"FirstCause": true,
"LastCause": false
},
{
"Number": 26,
"Content": " count = local.create_bucket \u0026\u0026 !var.is_directory_bucket ? 1 : 0",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mcount\u001b[0m = local.create_bucket \u001b[38;5;245m\u0026\u0026\u001b[0m \u001b[38;5;245m!\u001b[0m\u001b[38;5;33mvar\u001b[0m.is_directory_bucket \u001b[38;5;245m?\u001b[0m \u001b[38;5;37m1\u001b[0m \u001b[38;5;245m:\u001b[0m \u001b[38;5;37m0",
"FirstCause": false,
"LastCause": false
},
{
"Number": 27,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[0m",
"FirstCause": false,
"LastCause": false
},
{
"Number": 28,
"Content": " region = var.region",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mregion\u001b[0m = \u001b[38;5;33mvar\u001b[0m.region",
"FirstCause": false,
"LastCause": false
},
{
"Number": 29,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 30,
"Content": " bucket = var.bucket",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket",
"FirstCause": false,
"LastCause": false
},
{
"Number": 31,
"Content": " bucket_prefix = var.bucket_prefix",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket_prefix\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket_prefix",
"FirstCause": false,
"LastCause": false
},
{
"Number": 32,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 33,
"Content": " force_destroy = var.force_destroy",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mforce_destroy\u001b[0m = \u001b[38;5;33mvar\u001b[0m.force_destroy",
"FirstCause": false,
"LastCause": true
},
{
"Number": 34,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": true,
"FirstCause": false,
"LastCause": false
}
]
},
"Occurrences": [
{
"Resource": "module.bucket",
"Filename": "main.tf",
"Location": {
"StartLine": 1,
"EndLine": 5
}
}
]
}
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0089",
"AVDID": "AVD-AWS-0089",
"ID": "AWS-0089",
"Title": "S3 Bucket Logging",
"Description": "Ensures S3 bucket logging is enabled for S3 buckets",
"Message": "Bucket has logging disabled",
@@ -173,11 +36,11 @@
"Query": "data.builtin.aws.s3.aws0089.deny",
"Resolution": "Add a logging block to the resource to enable access logging",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0089",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0089",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html",
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html",
"https://avd.aquasec.com/misconfig/avd-aws-0089"
"https://avd.aquasec.com/misconfig/aws-0089"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -301,8 +164,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0090",
"AVDID": "AVD-AWS-0090",
"ID": "AWS-0090",
"Title": "S3 Data should be versioned",
"Description": "Versioning in Amazon S3 is a means of keeping multiple variants of an object in the same bucket.\n\nYou can use the S3 Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets.\n\nWith versioning you can recover more easily from both unintended user actions and application failures.\n\nWhen you enable versioning, also keep in mind the potential costs of storing noncurrent versions of objects. To help manage those costs, consider setting up an S3 Lifecycle configuration.\n",
"Message": "Bucket does not have versioning enabled",
@@ -310,11 +172,11 @@
"Query": "data.builtin.aws.s3.aws0090.deny",
"Resolution": "Enable versioning to protect against accidental/malicious removal or modification",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0090",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0090",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html",
"https://aws.amazon.com/blogs/storage/reduce-storage-costs-with-fewer-noncurrent-versions-using-amazon-s3-lifecycle/",
"https://avd.aquasec.com/misconfig/avd-aws-0090"
"https://avd.aquasec.com/misconfig/aws-0090"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -438,8 +300,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0132",
"AVDID": "AVD-AWS-0132",
"ID": "AWS-0132",
"Title": "S3 encryption should use Customer Managed Keys",
"Description": "Encryption using AWS keys provides protection for your S3 buckets. To gain greater control over encryption, such as key rotation, access policies, and auditability, use customer managed keys (CMKs) with SSE-KMS.\nNote that SSE-KMS is not supported for S3 server access logging destination buckets; in such cases, use SSE-S3 instead.\n",
"Message": "Bucket does not encrypt data with a customer managed key.",
@@ -447,10 +308,10 @@
"Query": "data.builtin.aws.s3.aws0132.deny",
"Resolution": "Use SSE-KMS with a customer managed key (CMK)",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0132",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0132",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0132"
"https://avd.aquasec.com/misconfig/aws-0132"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 56,
"Successes": 69,
"Failures": 0
}
},
@@ -28,8 +28,7 @@
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0104",
"AVDID": "AVD-AWS-0104",
"ID": "AWS-0104",
"Title": "A security group rule should not allow unrestricted egress to any IP address.",
"Description": "Opening up ports to connect out to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that are explicitly required where possible.\n",
"Message": "Security group rule allows unrestricted egress to any IP address.",
@@ -37,10 +36,10 @@
"Query": "data.builtin.aws.ec2.aws0104.deny",
"Resolution": "Set a more restrictive cidr range",
"Severity": "CRITICAL",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0104",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0104",
"References": [
"https://docs.aws.amazon.com/whitepapers/latest/building-scalable-secure-multi-vpc-network-infrastructure/centralized-egress-to-internet.html",
"https://avd.aquasec.com/misconfig/avd-aws-0104"
"https://avd.aquasec.com/misconfig/aws-0104"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -127,8 +126,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0124",
"AVDID": "AVD-AWS-0124",
"ID": "AWS-0124",
"Title": "Missing description for security group rule.",
"Description": "Security group rules should include a description for auditing purposes.\n\nSimplifies auditing, debugging, and managing security groups.\n",
"Message": "Security group rule does not have a description.",
@@ -136,10 +134,10 @@
"Query": "data.builtin.aws.ec2.aws0124.deny",
"Resolution": "Add descriptions for all security groups rules",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0124",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0124",
"References": [
"https://www.cloudconformity.com/knowledge-base/aws/EC2/security-group-rules-description.html",
"https://avd.aquasec.com/misconfig/avd-aws-0124"
"https://avd.aquasec.com/misconfig/aws-0124"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -13,7 +13,7 @@
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 45,
"Successes": 58,
"Failures": 0
}
},
@@ -23,149 +23,12 @@
"Type": "terraform",
"MisconfSummary": {
"Successes": 0,
"Failures": 4
"Failures": 3
},
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0088",
"AVDID": "AVD-AWS-0088",
"Title": "Unencrypted S3 bucket.",
"Description": "S3 Buckets should be encrypted to protect the data that is stored within them if access is compromised.\n",
"Message": "Bucket does not have encryption enabled",
"Namespace": "builtin.aws.s3.aws0088",
"Query": "data.builtin.aws.s3.aws0088.deny",
"Resolution": "Configure bucket encryption",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0088",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0088"
],
"Status": "FAIL",
"CauseMetadata": {
"Resource": "module.bucket",
"Provider": "AWS",
"Service": "s3",
"StartLine": 25,
"EndLine": 36,
"Code": {
"Lines": [
{
"Number": 25,
"Content": "resource \"aws_s3_bucket\" \"this\" {",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[38;5;33mresource\u001b[0m \u001b[38;5;37m\"aws_s3_bucket\"\u001b[0m \u001b[38;5;37m\"this\"\u001b[0m {",
"FirstCause": true,
"LastCause": false
},
{
"Number": 26,
"Content": " count = local.create_bucket \u0026\u0026 !var.is_directory_bucket ? 1 : 0",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mcount\u001b[0m = local.create_bucket \u001b[38;5;245m\u0026\u0026\u001b[0m \u001b[38;5;245m!\u001b[0m\u001b[38;5;33mvar\u001b[0m.is_directory_bucket \u001b[38;5;245m?\u001b[0m \u001b[38;5;37m1\u001b[0m \u001b[38;5;245m:\u001b[0m \u001b[38;5;37m0",
"FirstCause": false,
"LastCause": false
},
{
"Number": 27,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "\u001b[0m",
"FirstCause": false,
"LastCause": false
},
{
"Number": 28,
"Content": " region = var.region",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mregion\u001b[0m = \u001b[38;5;33mvar\u001b[0m.region",
"FirstCause": false,
"LastCause": false
},
{
"Number": 29,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 30,
"Content": " bucket = var.bucket",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket",
"FirstCause": false,
"LastCause": false
},
{
"Number": 31,
"Content": " bucket_prefix = var.bucket_prefix",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mbucket_prefix\u001b[0m = \u001b[38;5;33mvar\u001b[0m.bucket_prefix",
"FirstCause": false,
"LastCause": false
},
{
"Number": 32,
"Content": "",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 33,
"Content": " force_destroy = var.force_destroy",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": " \u001b[38;5;245mforce_destroy\u001b[0m = \u001b[38;5;33mvar\u001b[0m.force_destroy",
"FirstCause": false,
"LastCause": true
},
{
"Number": 34,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": true,
"FirstCause": false,
"LastCause": false
}
]
},
"Occurrences": [
{
"Resource": "module.bucket",
"Filename": "main.tf",
"Location": {
"StartLine": 1,
"EndLine": 5
}
}
]
}
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0089",
"AVDID": "AVD-AWS-0089",
"ID": "AWS-0089",
"Title": "S3 Bucket Logging",
"Description": "Ensures S3 bucket logging is enabled for S3 buckets",
"Message": "Bucket has logging disabled",
@@ -173,11 +36,11 @@
"Query": "data.builtin.aws.s3.aws0089.deny",
"Resolution": "Add a logging block to the resource to enable access logging",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0089",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0089",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html",
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html",
"https://avd.aquasec.com/misconfig/avd-aws-0089"
"https://avd.aquasec.com/misconfig/aws-0089"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -301,8 +164,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0090",
"AVDID": "AVD-AWS-0090",
"ID": "AWS-0090",
"Title": "S3 Data should be versioned",
"Description": "Versioning in Amazon S3 is a means of keeping multiple variants of an object in the same bucket.\n\nYou can use the S3 Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets.\n\nWith versioning you can recover more easily from both unintended user actions and application failures.\n\nWhen you enable versioning, also keep in mind the potential costs of storing noncurrent versions of objects. To help manage those costs, consider setting up an S3 Lifecycle configuration.\n",
"Message": "Bucket does not have versioning enabled",
@@ -310,11 +172,11 @@
"Query": "data.builtin.aws.s3.aws0090.deny",
"Resolution": "Enable versioning to protect against accidental/malicious removal or modification",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0090",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0090",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html",
"https://aws.amazon.com/blogs/storage/reduce-storage-costs-with-fewer-noncurrent-versions-using-amazon-s3-lifecycle/",
"https://avd.aquasec.com/misconfig/avd-aws-0090"
"https://avd.aquasec.com/misconfig/aws-0090"
],
"Status": "FAIL",
"CauseMetadata": {
@@ -438,8 +300,7 @@
},
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0132",
"AVDID": "AVD-AWS-0132",
"ID": "AWS-0132",
"Title": "S3 encryption should use Customer Managed Keys",
"Description": "Encryption using AWS keys provides protection for your S3 buckets. To gain greater control over encryption, such as key rotation, access policies, and auditability, use customer managed keys (CMKs) with SSE-KMS.\nNote that SSE-KMS is not supported for S3 server access logging destination buckets; in such cases, use SSE-S3 instead.\n",
"Message": "Bucket does not encrypt data with a customer managed key.",
@@ -447,10 +308,10 @@
"Query": "data.builtin.aws.s3.aws0132.deny",
"Resolution": "Use SSE-KMS with a customer managed key (CMK)",
"Severity": "HIGH",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0132",
"PrimaryURL": "https://avd.aquasec.com/misconfig/aws-0132",
"References": [
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html",
"https://avd.aquasec.com/misconfig/avd-aws-0132"
"https://avd.aquasec.com/misconfig/aws-0132"
],
"Status": "FAIL",
"CauseMetadata": {

View File

@@ -82,15 +82,18 @@ func DownloadVEXRepositories(ctx context.Context, opts flag.Options) error {
func InitBuiltinChecks(ctx context.Context, client *policy.Client, skipUpdate bool, registryOpts ftypes.RegistryOptions) (string, error) {
mu.Lock()
defer mu.Unlock()
ctx = log.WithContextPrefix(ctx, "checks-client")
var err error
if skipUpdate {
log.Info("No downloadable checks were loaded as --skip-check-update is enabled, loading from existing cache...")
log.InfoContext(ctx, "No downloadable checks were loaded as --skip-check-update is enabled, loading from existing cache...")
path := client.LoadBuiltinChecks()
path := client.BuiltinChecksPath()
_, _, err := misconf.CheckPathExists(path)
if err != nil {
return "", xerrors.Errorf("Failed to load existing cache, err: %s", err.Error())
return "", xerrors.Errorf("failed to check cache: %w", err)
}
return path, nil
}
@@ -106,9 +109,14 @@ func InitBuiltinChecks(ctx context.Context, client *policy.Client, skipUpdate bo
if err = client.DownloadBuiltinChecks(ctx, registryOpts); err != nil {
return "", xerrors.Errorf("failed to download checks bundle: %w", err)
}
} else {
log.InfoContext(ctx,
"Using existing checks from cache",
log.String("path", client.BuiltinChecksPath()),
)
}
return client.LoadBuiltinChecks(), nil
return client.BuiltinChecksPath(), nil
}
func Exit(opts flag.Options, failedResults bool, m types.Metadata) error {

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path/filepath"
@@ -14,6 +15,7 @@ import (
fakei "github.com/google/go-containerregistry/pkg/v1/fake"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/utils/clock"
@@ -74,6 +76,7 @@ func TestInitBuiltinChecks(t *testing.T) {
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
skipUpdate: false,
},
@@ -81,7 +84,7 @@ func TestInitBuiltinChecks(t *testing.T) {
name: "skip update flag set with no existing cache to fallback to",
skipUpdate: true,
checkDir: "policy",
wantErr: "Failed to load existing cache",
wantErr: "cache does not exist at",
},
{
name: "skip update flag set with existing cache to fallback to",
@@ -101,6 +104,7 @@ func TestInitBuiltinChecks(t *testing.T) {
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
checkDir: "policy",
clock: fake.NewFakeClock(time.Date(3000, 1, 1, 1, 0, 0, 0, time.UTC)),
@@ -162,6 +166,9 @@ func TestInitBuiltinChecks(t *testing.T) {
},
},
},
Annotations: map[string]string{
policy.VersionAnnotationKey: fmt.Sprintf("%d.0.0", policy.BundleVersion),
},
}, nil)
// Mock OCI artifact

View File

@@ -9,7 +9,7 @@ import (
"golang.org/x/xerrors"
"gopkg.in/yaml.v3"
"github.com/aquasecurity/trivy-checks/pkg/specs"
"github.com/aquasecurity/trivy-checks/pkg/compliance"
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/set"
@@ -61,17 +61,31 @@ func scannerByCheckID(checkID string) types.Scanner {
switch {
case strings.HasPrefix(checkID, "cve-") || strings.HasPrefix(checkID, "dla-"):
return types.VulnerabilityScanner
case strings.HasPrefix(checkID, "avd-"):
return types.MisconfigScanner
case strings.HasPrefix(checkID, "vuln-"): // custom id for filtering vulnerabilities by severity
return types.VulnerabilityScanner
case strings.HasPrefix(checkID, "secret-"): // custom id for filtering secrets by severity
return types.SecretScanner
// check the "avd-" prefix for backward compatibility
case strings.HasPrefix(checkID, "avd-") || isMisconfCheck(checkID):
return types.MisconfigScanner
default:
return types.UnknownScanner
}
}
var misconfPrefixes = set.New(
"aws", "azu", "nif", "dig", "oci", "cldstk", "git",
"gcp", "ksv", "kcv", "ds", "kube", "opnstk",
)
func isMisconfCheck(checkID string) bool {
prefix, _, ok := strings.Cut(checkID, "-")
if !ok {
return false
}
return misconfPrefixes.Contains(prefix)
}
func checksDir(cacheDir string) string {
return filepath.Join(cacheDir, "policy")
}
@@ -97,7 +111,7 @@ func GetComplianceSpec(specNameOrPath, cacheDir string) (ComplianceSpec, error)
} else {
_, err := os.Stat(filepath.Join(checksDir(cacheDir), "metadata.json"))
if err != nil { // cache corrupt or bundle does not exist, load embedded version
b = []byte(specs.GetSpec(specNameOrPath))
b = []byte(compliance.GetSpec(specNameOrPath))
log.Debug("Compliance spec loaded from embedded library", log.String("spec", specNameOrPath))
} else {
// load from bundle on disk

View File

@@ -22,7 +22,7 @@ import (
)
var (
disabledChecks = set.New("AVD-DS-0007", "AVD-DS-0016")
disabledChecks = set.New("DS-0007", "DS-0016")
reason = "See " + doc.URL("guide/target/container_image", "disabled-checks")
)
@@ -202,9 +202,9 @@ func (a *historyAnalyzer) Version() int {
func filterDisabledChecks(results types.MisconfResults) types.MisconfResults {
var filtered types.MisconfResults
for _, r := range results {
if disabledChecks.Contains(r.AVDID) {
if disabledChecks.Contains(r.ID) {
log.WithPrefix("image history analyzer").Info("Skip disabled check",
log.String("ID", r.AVDID), log.String("reason", reason))
log.String("ID", r.ID), log.String("reason", reason))
continue
}
filtered = append(filtered, r)

View File

@@ -101,8 +101,8 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
Query: "data.builtin.dockerfile.DS005.deny",
Message: "Consider using 'COPY foo.txt /' command instead of 'ADD foo.txt /'",
PolicyMetadata: types.PolicyMetadata{
ID: "DS005",
AVDID: "AVD-DS-0005",
ID: "DS-0005",
AVDID: "",
Type: "Dockerfile Security Check",
Title: "ADD instead of COPY",
Description: "You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.",
@@ -188,8 +188,8 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
Query: "data.builtin.dockerfile.DS005.deny",
Message: "Consider using 'COPY ./foo.txt /foo.txt' command instead of 'ADD ./foo.txt /foo.txt'",
PolicyMetadata: types.PolicyMetadata{
ID: "DS005",
AVDID: "AVD-DS-0005",
ID: "DS-0005",
AVDID: "",
Type: "Dockerfile Security Check",
Title: "ADD instead of COPY",
Description: "You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.",
@@ -262,8 +262,8 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
Query: "data.builtin.dockerfile.DS002.deny",
Message: "Specify at least 1 USER command in Dockerfile with non-root user as argument",
PolicyMetadata: types.PolicyMetadata{
ID: "DS002",
AVDID: "AVD-DS-0002",
ID: "DS-0002",
AVDID: "",
Type: "Dockerfile Security Check",
Title: "Image user should not be 'root'",
Description: "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",

View File

@@ -102,6 +102,7 @@ func getVersioning(block *terraform.Block, a *adapter) s3.Versioning {
}
if enabled, ok := applyForBucketRelatedResource(a, block, "aws_s3_bucket_object_lock_configuration", func(resource *terraform.Block) *iacTypes.BoolValue {
// TODO: object_lock_enabled is a string
if block.GetAttribute("object_lock_enabled").IsTrue() {
return isObjeckLockEnabled(resource)
}

View File

@@ -57,7 +57,7 @@ func RegisterRegoRules(modules map[string]*ast.Module) {
continue
}
if metadata.AVDID == "" {
if metadata.ID == "" {
if !metadata.Library {
log.Warn("Check ID is empty", log.FilePath(module.Package.Location.File))
}

View File

@@ -28,12 +28,12 @@ func TestScanner_ScanFS(t *testing.T) {
name: "archived chart",
target: filepath.Join("testdata", "mysql-8.8.26.tar"),
assert: assertIds([]string{
"KSV001", "KSV003",
"KSV011", "KSV012", "KSV014",
"KSV015", "KSV016", "KSV018",
"KSV020", "KSV021", "KSV030",
"KSV104", "KSV106", "KSV0125",
"KSV004",
"KSV-0001", "KSV-0003",
"KSV-0011", "KSV-0012", "KSV-0014",
"KSV-0015", "KSV-0016", "KSV-0018",
"KSV-0020", "KSV-0021", "KSV-0030",
"KSV-0104", "KSV-0106", "KSV-0125",
"KSV-0004",
}),
},
{
@@ -41,19 +41,19 @@ func TestScanner_ScanFS(t *testing.T) {
target: filepath.Join("testdata", "testchart"),
assert: func(t *testing.T, results scan.Results) {
assertIds([]string{
"KSV001", "KSV003",
"KSV011", "KSV012", "KSV014",
"KSV015", "KSV016",
"KSV020", "KSV021", "KSV030",
"KSV104", "KSV106",
"KSV117", "KSV110", "KSV118",
"KSV004",
"KSV-0001", "KSV-0003",
"KSV-0011", "KSV-0012", "KSV-0014",
"KSV-0015", "KSV-0016",
"KSV-0020", "KSV-0021", "KSV-0030",
"KSV-0104", "KSV-0106",
"KSV-0117", "KSV-0110", "KSV-0118",
"KSV-0004",
})(t, results)
ignored := results.GetIgnored()
assert.Len(t, ignored, 1)
assert.Equal(t, "KSV018", ignored[0].Rule().ID)
assert.Equal(t, "KSV-0018", ignored[0].Rule().ID)
assert.Equal(t, "testchart/templates/deployment.yaml", ignored[0].Metadata().Range().GetFilename())
},
},
@@ -62,12 +62,12 @@ func TestScanner_ScanFS(t *testing.T) {
name: "scanner with missing chart name can recover",
target: filepath.Join("testdata", "aws-cluster-autoscaler-bad.tar.gz"),
assert: assertIds([]string{
"KSV014", "KSV023", "KSV030",
"KSV104", "KSV003", "KSV018",
"KSV118", "KSV012", "KSV106",
"KSV016", "KSV001", "KSV011",
"KSV015", "KSV021", "KSV110", "KSV020",
"KSV004",
"KSV-0014", "KSV-0023", "KSV-0030",
"KSV-0104", "KSV-0003", "KSV-0018",
"KSV-0118", "KSV-0012", "KSV-0106",
"KSV-0016", "KSV-0001", "KSV-0011",
"KSV-0015", "KSV-0021", "KSV-0110", "KSV-0020",
"KSV-0004",
}),
},
{
@@ -96,12 +96,12 @@ deny[res] {
}`)),
},
assert: assertIds([]string{
"KSV001", "KSV003",
"KSV011", "KSV012", "KSV014",
"KSV015", "KSV016", "KSV018",
"KSV020", "KSV021", "KSV030",
"KSV104", "KSV106", "USR-ID001",
"KSV004", "KSV0125",
"KSV-0001", "KSV-0003",
"KSV-0011", "KSV-0012", "KSV-0014",
"KSV-0015", "KSV-0016", "KSV-0018",
"KSV-0020", "KSV-0021", "KSV-0030",
"KSV-0104", "KSV-0106", "USR-ID001",
"KSV-0004", "KSV-0125",
}),
},
{

View File

@@ -55,14 +55,14 @@ func TestScanner_ScanFS(t *testing.T) {
rego.WithEmbeddedLibraries(true),
},
expected: []string{
"AVD-AWS-0093",
"AVD-AWS-0086",
"AVD-AWS-0132",
"AVD-AWS-0094",
"AVD-AWS-0087",
"AVD-AWS-0091",
"AVD-AWS-0099",
"AVD-AWS-0124",
"AWS-0093",
"AWS-0086",
"AWS-0132",
"AWS-0094",
"AWS-0087",
"AWS-0091",
"AWS-0099",
"AWS-0124",
},
},
{

View File

@@ -427,7 +427,7 @@ func CheckPathExists(path string) (fs.FileInfo, string, error) {
}
fi, err := os.Stat(abs)
if errors.Is(err, os.ErrNotExist) {
return nil, "", xerrors.Errorf("check file %q not found", abs)
return nil, "", xerrors.Errorf("cache does not exist at %q", abs)
} else if err != nil {
return nil, "", xerrors.Errorf("file %q stat error: %w", abs, err)
}

View File

@@ -219,6 +219,19 @@ func (a *Artifact) Digest(ctx context.Context) (string, error) {
return digest.String(), nil
}
func (a *Artifact) Manifest(ctx context.Context) (*v1.Manifest, error) {
if err := a.populate(ctx, a.RegistryOptions); err != nil {
return nil, err
}
manifest, err := a.image.Manifest()
if err != nil {
return nil, xerrors.Errorf("get manifest: %w", err)
}
return manifest, nil
}
type Artifacts []*Artifact
// NewArtifacts returns a slice of artifacts.

View File

@@ -3,7 +3,9 @@ package policy
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"time"
@@ -11,16 +13,20 @@ import (
"golang.org/x/xerrors"
"k8s.io/utils/clock"
"github.com/aquasecurity/go-version/pkg/part"
"github.com/aquasecurity/go-version/pkg/semver"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/oci"
)
const (
BundleVersion = 1 // Latest released MAJOR version for trivy-checks
BundleVersion = 2 // Latest released MAJOR version for trivy-checks
BundleRepository = "mirror.gcr.io/aquasec/trivy-checks"
policyMediaType = "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip"
updateInterval = 24 * time.Hour
VersionAnnotationKey = "org.opencontainers.image.version"
)
type options struct {
@@ -57,6 +63,16 @@ type Client struct {
type Metadata struct {
Digest string
DownloadedAt time.Time
// MajorVersion indicates the major version of the bundle.
// Used to invalidate cache when the major version increases.
// Nil for old cache entries. Set to 0 for custom builds.
MajorVersion *int `json:",omitempty"`
// CustomBuild is true if the bundle was built manually and did not go
// through the official build process that enriches the manifest with additional data.
// For custom builds, MajorVersion is not used for cache invalidation.
CustomBuild bool `json:",omitempty"`
}
func (m Metadata) String() string {
@@ -88,16 +104,17 @@ func NewClient(cacheDir string, quiet bool, checkBundleRepo string, opts ...Opti
}, nil
}
func (c *Client) populateOCIArtifact(ctx context.Context, registryOpts types.RegistryOptions) {
func (c *Client) initOCIArtifact(ctx context.Context, registryOpts types.RegistryOptions) {
if c.artifact == nil {
log.DebugContext(ctx, "Loading check bundle", log.String("repository", c.checkBundleRepo))
log.DebugContext(ctx, "Initializing OCI checks bundle artifact",
log.String("repository", c.checkBundleRepo))
c.artifact = oci.NewArtifact(c.checkBundleRepo, registryOpts)
}
}
// DownloadBuiltinChecks download default policies from GitHub Pages
func (c *Client) DownloadBuiltinChecks(ctx context.Context, registryOpts types.RegistryOptions) error {
c.populateOCIArtifact(ctx, registryOpts)
c.initOCIArtifact(ctx, registryOpts)
dst := c.contentDir()
if err := c.artifact.Download(ctx, dst, oci.DownloadOption{
@@ -112,47 +129,137 @@ func (c *Client) DownloadBuiltinChecks(ctx context.Context, registryOpts types.R
if err != nil {
return xerrors.Errorf("digest error: %w", err)
}
log.DebugContext(ctx, "Digest of the built-in checks", log.String("digest", digest))
ver, err := c.getBundleMajorVersion(ctx)
if err != nil {
return xerrors.Errorf("get bundle version: %w", err)
}
isCustomBundle := ver == 0
if isCustomBundle {
log.DebugContext(ctx, "Built-in checks (custom build)",
log.String("digest", digest))
} else {
log.DebugContext(ctx, "Built-in checks",
log.String("digest", digest), log.Int("major_version", ver))
}
// Update metadata.json with the new digest and the current date
if err = c.updateMetadata(digest, c.clock.Now()); err != nil {
if err = c.updateMetadata(Metadata{
Digest: digest,
DownloadedAt: c.clock.Now(),
MajorVersion: &ver,
CustomBuild: isCustomBundle,
}); err != nil {
return xerrors.Errorf("unable to update the check metadata: %w", err)
}
return nil
}
// LoadBuiltinChecks loads default policies
func (c *Client) LoadBuiltinChecks() string {
// BuiltinChecksPath returns default policies
func (c *Client) BuiltinChecksPath() string {
return c.contentDir()
}
func (c *Client) getBundleMajorVersion(ctx context.Context) (ver int, err error) {
manifest, err := c.artifact.Manifest(ctx)
if err != nil {
return 0, err
}
// No annotations → treat as custom build
if manifest.Annotations == nil {
return 0, nil
}
v, ok := manifest.Annotations[VersionAnnotationKey]
if !ok || v == "" {
return 0, nil
}
version, err := semver.Parse(v)
if err != nil {
// Invalid version → treat as custom build
return 0, nil
}
majorPart, ok := version.Major().(part.Uint64)
if !ok {
// Could not extract major part → treat as custom build
return 0, nil
}
return int(majorPart), nil
}
// NeedsUpdate returns if the default check should be updated
func (c *Client) NeedsUpdate(ctx context.Context, registryOpts types.RegistryOptions) (bool, error) {
meta, err := c.GetMetadata(ctx)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
log.DebugContext(ctx, "Cache does not exist, will be created")
} else {
log.DebugContext(ctx,
"Invalidating cache: failed to get metadata", log.Err(err),
)
}
return true, nil
}
// For official builds, check the major version for cache invalidation.
// Custom builds may not have a version annotation, so MajorVersion is ignored.
// Old cache entries without a version will be invalidated once to enrich metadata.
if !meta.CustomBuild {
// Invalidate the old cache if it does not store the version.
if meta.MajorVersion == nil {
log.DebugContext(ctx,
"Invalidating cache: missing major version",
log.String("digest", meta.Digest),
log.Time("downloaded_at", meta.DownloadedAt),
)
return true, nil
}
// Invalidate the old cache if its version does not match.
if *meta.MajorVersion != BundleVersion {
log.DebugContext(ctx, "Invalidating cache: version mismatch",
log.Int("cached_major_version", *meta.MajorVersion),
log.Int("current_major_version", BundleVersion),
)
return true, nil
}
}
// No need to update if it's been within a day since the last update.
if c.clock.Now().Before(meta.DownloadedAt.Add(updateInterval)) {
return false, nil
}
c.populateOCIArtifact(ctx, registryOpts)
c.initOCIArtifact(ctx, registryOpts)
digest, err := c.artifact.Digest(ctx)
if err != nil {
return false, xerrors.Errorf("digest error: %w", err)
}
if meta.Digest != digest {
log.DebugContext(ctx, "Invalidating cache: digest mismatch",
log.String("cached_digest", meta.Digest),
log.String("current_digest", digest),
)
return true, nil
}
// Update DownloadedAt with the current time.
// Otherwise, if there are no updates in the remote registry,
// the digest will be fetched every time even after this.
if err = c.updateMetadata(meta.Digest, time.Now()); err != nil {
if err = c.updateMetadata(Metadata{
Digest: meta.Digest,
DownloadedAt: c.clock.Now(),
MajorVersion: meta.MajorVersion,
CustomBuild: meta.CustomBuild,
}); err != nil {
return false, xerrors.Errorf("unable to update the check metadata: %w", err)
}
@@ -167,18 +274,13 @@ func (c *Client) metadataPath() string {
return filepath.Join(c.policyDir, "metadata.json")
}
func (c *Client) updateMetadata(digest string, now time.Time) error {
func (c *Client) updateMetadata(meta Metadata) error {
f, err := os.Create(c.metadataPath())
if err != nil {
return xerrors.Errorf("failed to open checks bundle metadata: %w", err)
}
defer f.Close()
meta := Metadata{
Digest: digest,
DownloadedAt: now,
}
if err = json.NewEncoder(f).Encode(meta); err != nil {
return xerrors.Errorf("json encode error: %w", err)
}

View File

@@ -3,7 +3,9 @@ package policy_test
import (
"encoding/json"
"errors"
"fmt"
"io"
"maps"
"os"
"path/filepath"
"testing"
@@ -13,6 +15,7 @@ import (
fakei "github.com/google/go-containerregistry/pkg/v1/fake"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/utils/clock"
@@ -97,7 +100,7 @@ func TestClient_LoadBuiltinChecks(t *testing.T) {
c, err := policy.NewClient(tt.cacheDir, true, "", policy.WithOCIArtifact(art))
require.NoError(t, err)
got := c.LoadBuiltinChecks()
got := c.BuiltinChecksPath()
if tt.wantErr != "" {
require.ErrorContains(t, err, tt.wantErr)
return
@@ -108,61 +111,67 @@ func TestClient_LoadBuiltinChecks(t *testing.T) {
}
}
type annotations = map[string]string
func TestClient_NeedsUpdate(t *testing.T) {
type digestReturns struct {
h v1.Hash
err error
}
imageDigest := digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
}
usedBundleVersion := fmt.Sprintf("%d.0.0", policy.BundleVersion)
tests := []struct {
name string
clock clock.Clock
digestReturns digestReturns
metadata any
want bool
wantMetadata *policy.Metadata
wantErr bool
}{
{
name: "recent download",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
name: "recent download",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
want: false,
},
{
name: "same digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
name: "same digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
want: false,
wantMetadata: &policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
},
{
name: "different digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
name: "different digest",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
want: true,
},
@@ -175,6 +184,7 @@ func TestClient_NeedsUpdate(t *testing.T) {
metadata: policy.Metadata{
Digest: `sha256:922e50f14ab484f11ae65540c3d2d76009020213f1027d4331d31141575e5414`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
want: false,
wantErr: true,
@@ -190,6 +200,45 @@ func TestClient_NeedsUpdate(t *testing.T) {
metadata: `"foo"`,
want: true,
},
{
name: "old metadata without version",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
want: true,
},
{
name: "version mismatched",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(1),
},
want: true,
},
{
name: "version mismatched but custom build",
clock: fake.NewFakeClock(time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC)),
digestReturns: imageDigest,
metadata: policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
CustomBuild: true,
MajorVersion: lo.ToPtr(1),
},
want: false,
wantMetadata: &policy.Metadata{
Digest: `sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d`,
DownloadedAt: time.Date(2021, 1, 2, 1, 0, 0, 0, time.UTC),
CustomBuild: true,
MajorVersion: lo.ToPtr(1),
},
},
}
for _, tt := range tests {
@@ -215,6 +264,9 @@ func TestClient_NeedsUpdate(t *testing.T) {
},
},
},
Annotations: annotations{
policy.VersionAnnotationKey: usedBundleVersion,
},
}, nil)
// Create a check directory
@@ -237,8 +289,29 @@ func TestClient_NeedsUpdate(t *testing.T) {
// Assert results
got, err := c.NeedsUpdate(t.Context(), ftypes.RegistryOptions{})
assert.Equal(t, tt.wantErr, err != nil)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.Equal(t, tt.want, got)
// Verify that metadata has been updated correctly
if metadata, ok := tt.metadata.(policy.Metadata); ok {
metadataPath := filepath.Join(tmpDir, "policy", "metadata.json")
b, err := os.ReadFile(metadataPath)
require.NoError(t, err)
var want policy.Metadata
err = json.Unmarshal(b, &want)
require.NoError(t, err)
if tt.wantMetadata == nil {
// Metadata has not been changed
tt.wantMetadata = lo.ToPtr(metadata)
}
assert.Equal(t, tt.wantMetadata, &want)
}
})
}
}
@@ -257,6 +330,7 @@ func TestClient_DownloadBuiltinChecks(t *testing.T) {
clock clock.Clock
layersReturns layersReturns
digestReturns digestReturns
annotations annotations
want *policy.Metadata
wantErr string
}{
@@ -275,6 +349,7 @@ func TestClient_DownloadBuiltinChecks(t *testing.T) {
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
DownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(policy.BundleVersion),
},
},
{
@@ -300,11 +375,71 @@ func TestClient_DownloadBuiltinChecks(t *testing.T) {
digestReturns: digestReturns{
err: errors.New("error"),
},
wantErr: "digest error",
},
{
name: "custom bundle",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{newFakeLayer(t)},
},
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
annotations: annotations{},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
DownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(0),
CustomBuild: true,
},
},
{
name: "invalid version is treated as a custom build",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{newFakeLayer(t)},
},
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
annotations: annotations{
policy.VersionAnnotationKey: "dev",
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
DownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(0),
CustomBuild: true,
},
},
{
name: "nightly build",
clock: fake.NewFakeClock(time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC)),
layersReturns: layersReturns{
layers: []v1.Layer{newFakeLayer(t)},
},
digestReturns: digestReturns{
h: v1.Hash{
Algorithm: "sha256",
Hex: "01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
},
},
annotations: annotations{
policy.VersionAnnotationKey: "2.0.1-nightly.20260129",
},
want: &policy.Metadata{
Digest: "sha256:01e033e78bd8a59fa4f4577215e7da06c05e1152526094d8d79d2aa06e98cb9d",
DownloadedAt: time.Date(2021, 1, 1, 1, 0, 0, 0, time.UTC),
MajorVersion: lo.ToPtr(2),
CustomBuild: false,
},
wantErr: "digest error",
},
}
@@ -316,7 +451,8 @@ func TestClient_DownloadBuiltinChecks(t *testing.T) {
img := new(fakei.FakeImage)
img.DigestReturns(tt.digestReturns.h, tt.digestReturns.err)
img.LayersReturns(tt.layersReturns.layers, tt.layersReturns.err)
img.ManifestReturns(&v1.Manifest{
manifest := &v1.Manifest{
Layers: []v1.Descriptor{
{
MediaType: "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip",
@@ -330,7 +466,17 @@ func TestClient_DownloadBuiltinChecks(t *testing.T) {
},
},
},
}, nil)
Annotations: make(map[string]string),
}
if tt.annotations != nil {
maps.Copy(manifest.Annotations, tt.annotations)
} else {
// Set default version
manifest.Annotations[policy.VersionAnnotationKey] = fmt.Sprintf("%d.0.0", policy.BundleVersion)
}
img.ManifestReturns(manifest, nil)
// Mock OCI artifact
art := oci.NewArtifact("repo", ftypes.RegistryOptions{}, oci.WithImage(img))