From a9d4e7569b101378ef3fa5cd3b17710d035e7188 Mon Sep 17 00:00:00 2001 From: Santosh Date: Thu, 16 May 2024 14:45:48 +0530 Subject: [PATCH] Enhancement in printing results for regoval command and re-organizing Rego policies Signed-off-by: Santosh --- pkg/validate/printresults.go | 65 ++++++----- pkg/validate/regometa.go | 77 ++++++++++++ pkg/validate/regometadata.go | 16 +++ pkg/validate/regoval.go | 25 +++- pkg/validate/validatedockerfile.go | 110 +++++++++++------- pkg/validate/validateinputfile.go | 29 ++++- .../docker_policies/deny_add/deny_add.json | 9 ++ .../docker_policies/deny_add/deny_add.rego | 10 ++ .../deny_caching/deny_caching.json | 9 ++ .../deny_caching/deny_caching.rego | 15 +++ .../deny_root_user/deny_root_user.json | 9 ++ .../deny_root_user/deny_root_user.rego | 13 +++ .../docker_policies/deny_sudo/deny_sudo.json | 9 ++ .../docker_policies/deny_sudo/deny_sudo.rego | 12 ++ .../trusted_base_image.json | 9 ++ .../trusted_base_image.rego | 13 +++ .../user_defined/user_defined.json | 9 ++ .../user_defined/user_defined.rego | 11 ++ .../rego/dockerfile_policies.rego | 2 +- 19 files changed, 367 insertions(+), 85 deletions(-) create mode 100644 pkg/validate/regometa.go create mode 100644 pkg/validate/regometadata.go create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.json create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.rego create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.json create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.rego create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.json create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.rego create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.json create mode 100644 templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.rego create mode 100644 templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.json create mode 100644 templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.rego create mode 100644 templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.json create mode 100644 templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.rego diff --git a/pkg/validate/printresults.go b/pkg/validate/printresults.go index eab50a3d..28bc131a 100644 --- a/pkg/validate/printresults.go +++ b/pkg/validate/printresults.go @@ -8,56 +8,57 @@ import ( "github.com/fatih/color" "github.com/jedib0t/go-pretty/v6/table" "github.com/open-policy-agent/opa/rego" - log "github.com/sirupsen/logrus" ) -func PrintResults(result rego.ResultSet) error { +// PrintResults prints the evaluation results along with the metadata +func PrintResults(result rego.ResultSet, metas []*regoMetadata) error { + // Create the table t := table.NewWriter() t.SetOutputMirror(os.Stdout) - t.AppendHeader(table.Row{"Policy", "Status", "Description"}) + t.AppendHeader(table.Row{"Policy Name", "Status", "Description", "Severity", "Benchmark", "Category"}) + var policyError error - var desc string + + // Match policy metadata outside the loop + matchedKey, meta, err := MatchPolicyMetadata(metas, result) + if err != nil { + return fmt.Errorf("error matching key and metadata name: %v", err) + } + for _, r := range result { if len(r.Expressions) > 0 { keys := r.Expressions[0].Value.(map[string]interface{}) for key, value := range keys { - switch v := value.(type) { - case []interface{}: - // Check if the slice is not empty - if len(v) > 0 { - // If it's not empty, take the first element - desc = fmt.Sprintf("%v", v[0]) - } - case string: - // If value is a string, assign it to desc - desc = v - } - - // Perform type assertion to check if value is a slice - if slice, ok := value.([]interface{}); ok { - // Check if the slice is empty - if len(slice) > 0 { - t.AppendRow(table.Row{key, color.New(color.FgGreen).Sprint("passed"), desc}) - } else { - t.AppendRow(table.Row{key, color.New(color.FgRed).Sprint("failed"), "NA"}) - policyError = errors.New("policy evaluation failed: " + key) - } - } else { - // Handle other types of values (non-slice) - if value != nil { - t.AppendRow(table.Row{key, color.New(color.FgGreen).Sprint("passed"), desc}) + // Construct rows using the matched metadata + if key == matchedKey { + var status string + if policies, ok := value.([]interface{}); ok { + // Check if the slice is empty + if len(policies) > 0 { + status = color.New(color.FgGreen).Sprint("passed") + } else { + status = color.New(color.FgRed).Sprint("failed") + policyError = errors.New("policy evaluation failed: " + key) + } } else { - t.AppendRow(table.Row{key, color.New(color.FgRed).Sprint("failed"), "NA"}) - policyError = errors.New("policy evaluation failed: " + key) + // Handle other types of values (non-slice) + if value != nil { + status = color.New(color.FgGreen).Sprint("passed") + } else { + status = color.New(color.FgRed).Sprint("failed") + policyError = errors.New("policy evaluation failed: " + key) + } } + t.AppendRow([]interface{}{key, status, meta.Description, meta.Severity, meta.Benchmark, meta.Category}) } } } else { - log.Error("No policies passed") + fmt.Println("No policies passed") policyError = errors.New("no policies passed") } } + // Render the table t.Render() return policyError diff --git a/pkg/validate/regometa.go b/pkg/validate/regometa.go new file mode 100644 index 00000000..6adec177 --- /dev/null +++ b/pkg/validate/regometa.go @@ -0,0 +1,77 @@ +package validate + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/open-policy-agent/opa/rego" +) + +func FetchRegoMetadata(policyDir, metaExt, regoExt string) ([]string, []string, error) { + var metaFiles []string + var regoFiles []string + + err := filepath.Walk(policyDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() { + if filepath.Ext(info.Name()) == metaExt { + metaFiles = append(metaFiles, path) + } else if filepath.Ext(info.Name()) == regoExt { + regoFiles = append(regoFiles, path) + } + } + + return nil + }) + + if len(regoFiles) == 0 { + return nil, nil, fmt.Errorf("no Rego policy file found in the directory: %s", policyDir) + } + + return metaFiles, regoFiles, err +} + +// LoadRegoMetadata loads the contents of the metadata files into a slice of pointers to RegoMeta structs +func LoadRegoMetadata(filePaths []string) ([]*regoMetadata, error) { + var metas []*regoMetadata + + for _, path := range filePaths { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + + var meta regoMetadata + err = json.NewDecoder(file).Decode(&meta) + if err != nil { + return nil, err + } + + metas = append(metas, &meta) + } + + return metas, nil +} + +// MatchPolicyMetadata matches the RegoMeta policy names with the Rego evaluation results and returns the matched key +func MatchPolicyMetadata(metas []*regoMetadata, results rego.ResultSet) (string, *regoMetadata, error) { + for _, r := range results { + if len(r.Expressions) > 0 { + keys := r.Expressions[0].Value.(map[string]interface{}) + for key := range keys { + for _, meta := range metas { + if key == meta.PolicyName { + return key, meta, nil + } + } + } + } + } + return "", nil, fmt.Errorf("no matching policy name found") +} diff --git a/pkg/validate/regometadata.go b/pkg/validate/regometadata.go new file mode 100644 index 00000000..9d505daf --- /dev/null +++ b/pkg/validate/regometadata.go @@ -0,0 +1,16 @@ +package validate + +type regoMetadata struct { + Name string `json:"name"` + PolicyName string `json:"policy_name"` + PolicyFile string `json:"policy_file"` + Severity string `json:"severity"` + Description string `json:"description"` + Benchmark string `json:"benchmark"` + Category string `json:"category"` +} + +const ( + metaExt = ".json" + policyExt = ".rego" +) diff --git a/pkg/validate/regoval.go b/pkg/validate/regoval.go index 9bfc8a2e..d561f09b 100644 --- a/pkg/validate/regoval.go +++ b/pkg/validate/regoval.go @@ -11,14 +11,23 @@ import ( log "github.com/sirupsen/logrus" ) -func ValidateWithRego(inputContent string, regoPolicy string) error { +func ValidateWithRego(inputContent string, regoPolicyPath string) error { // read input is a file jsonData, err := parser.ProcessInput(inputContent) if err != nil { log.Errorf("Error reading input content file: %v", err) } - k8sPolicy, err := utils.ReadFile(regoPolicy) + metaFiles, regoPolicy, err := FetchRegoMetadata(regoPolicyPath, metaExt, policyExt) + if err != nil { + return err + } + var regoFile string + for _, v := range regoPolicy { + regoFile = v + } + + k8sPolicy, err := utils.ReadFile(regoFile) if err != nil { log.WithError(err).Error("Error reading the policy file") return err @@ -40,7 +49,7 @@ func ValidateWithRego(inputContent string, regoPolicy string) error { // Create regoQuery for evaluation regoQuery := rego.New( rego.Query("data."+pkg), - rego.Module(regoPolicy, string(k8sPolicy)), + rego.Module(regoFile, string(k8sPolicy)), rego.Input(commands), ) @@ -51,8 +60,14 @@ func ValidateWithRego(inputContent string, regoPolicy string) error { return err } - if err := PrintResults(rs); err != nil { - return fmt.Errorf("error evaluating rego results fron policy %s: %v", regoPolicy, err) + // Load metadata from JSON files + metas, err := LoadRegoMetadata(metaFiles) + if err != nil { + return fmt.Errorf("error loading policy metadata: %v", err) + } + + if err := PrintResults(rs, metas); err != nil { + return fmt.Errorf("error evaluating rego results for %s: %v", regoPolicyPath, err) } return nil } diff --git a/pkg/validate/validatedockerfile.go b/pkg/validate/validatedockerfile.go index 47dce38b..ecdc76b7 100644 --- a/pkg/validate/validatedockerfile.go +++ b/pkg/validate/validatedockerfile.go @@ -13,66 +13,90 @@ import ( log "github.com/sirupsen/logrus" ) +// ValidateDockerfileUsingRego validates a Dockerfile using Rego. // ValidateDockerfileUsingRego validates a Dockerfile using Rego. func ValidateDockerfile(dockerfileContent string, regoPolicyPath string) error { - dockerPolicy, err := utils.ReadFile(regoPolicyPath) + metaFiles, regoPolicy, err := FetchRegoMetadata(regoPolicyPath, metaExt, policyExt) if err != nil { - return fmt.Errorf("error reading the policy file %v: %v", regoPolicyPath, err) + return err } - pkg, err := utils.ExtractPackageName(dockerPolicy) + // Load metadata from JSON files + metas, err := LoadRegoMetadata(metaFiles) if err != nil { - return fmt.Errorf("errr fetching package name from polcy %v: %v", dockerPolicy, err) + return fmt.Errorf("error loading policy metadata: %v", err) } - // Prepare Rego input data - dockerfileInstructions := parser.ParseDockerfileContent(dockerfileContent) + // Declare a slice to store the results of each policy evaluation + var allResults []rego.ResultSet - jsonData, err := json.Marshal(dockerfileInstructions) - if err != nil { - return fmt.Errorf("error marshalling %v, to JSON: %v", dockerfileInstructions, err) - } + for _, regoFile := range regoPolicy { + dockerPolicy, err := utils.ReadFile(regoFile) + if err != nil { + return fmt.Errorf("error reading the policy file %v: %v", regoPolicy, err) + } - policyName := filepath.Base(regoPolicyPath) + pkg, err := utils.ExtractPackageName(dockerPolicy) + if err != nil { + return fmt.Errorf("errr fetching package name from polcy %v: %v", dockerPolicy, err) + } - var commands []map[string]string - err = json.Unmarshal([]byte(jsonData), &commands) - if err != nil { - return fmt.Errorf("error converting JSON to map: %v", err) - } + // Prepare Rego input data + dockerfileInstructions := parser.ParseDockerfileContent(dockerfileContent) - ctx := context.Background() + jsonData, err := json.Marshal(dockerfileInstructions) + if err != nil { + return fmt.Errorf("error marshalling %v, to JSON: %v", dockerfileInstructions, err) + } - compiler, err := ast.CompileModules(map[string]string{ - policyName: string(dockerPolicy), - }) - if err != nil { - log.Fatal(err) - return fmt.Errorf("failed to compile rego policy: %w", err) - } - // Create regoQuery for evaluation - regoQuery := rego.New( - rego.Query("data."+pkg), - rego.Compiler(compiler), - rego.Input(commands), - ) - - // Evaluate the Rego query - rs, err := regoQuery.Eval(ctx) - if err != nil { - switch err := err.(type) { - case ast.Errors: - for _, e := range err { - fmt.Printf("code: %v", e.Code) - fmt.Printf("row: %v", e.Location.Row) - fmt.Printf("filename: %v", e.Location.File) + policyName := filepath.Base(regoFile) + + var commands []map[string]string + err = json.Unmarshal([]byte(jsonData), &commands) + if err != nil { + return fmt.Errorf("error converting JSON to map: %v", err) + } + + ctx := context.Background() + + compiler, err := ast.CompileModules(map[string]string{ + policyName: string(dockerPolicy), + }) + if err != nil { + log.Fatal(err) + return fmt.Errorf("failed to compile rego policy: %w", err) + } + // Create regoQuery for evaluation + regoQuery := rego.New( + rego.Query("data."+pkg), + rego.Compiler(compiler), + rego.Input(commands), + ) + + // Evaluate the Rego query + rs, err := regoQuery.Eval(ctx) + if err != nil { + switch err := err.(type) { + case ast.Errors: + for _, e := range err { + fmt.Printf("code: %v", e.Code) + fmt.Printf("row: %v", e.Location.Row) + fmt.Printf("filename: %v", e.Location.File) + } + log.Fatal("Error evaluating query:", err) } - log.Fatal("Error evaluating query:", err) } + + // Store the results in the slice + allResults = append(allResults, rs) } - if err := PrintResults(rs); err != nil { - return fmt.Errorf("error evaluating rego results for %s: %v", regoPolicyPath, err) + // Print all results accumulated from each policy evaluation + for _, rs := range allResults { + if err := PrintResults(rs, metas); err != nil { + return fmt.Errorf("error evaluating rego results for %s: %v", regoPolicyPath, err) + } } + return nil } diff --git a/pkg/validate/validateinputfile.go b/pkg/validate/validateinputfile.go index 4de8450d..d8b80de6 100644 --- a/pkg/validate/validateinputfile.go +++ b/pkg/validate/validateinputfile.go @@ -29,8 +29,18 @@ func ValidateInput(yamlContent string, regoPolicyPath string) error { } ctx := context.Background() + metaFiles, regoPolicy, err := FetchRegoMetadata(regoPolicyPath, metaExt, policyExt) + if err != nil { + return err + } + + var regoFile string + for _, v := range regoPolicy { + regoFile = v + } + // Read the Rego policy from the given path - regoContent, err := utils.ReadFile(regoPolicyPath) + regoContent, err := utils.ReadFile(regoFile) if err != nil { return fmt.Errorf("error reading Rego policy: %v", err) } @@ -43,7 +53,7 @@ func ValidateInput(yamlContent string, regoPolicyPath string) error { // Create Rego for query and evaluation regoQuery := rego.New( rego.Query("data."+pkg), - rego.Module(regoPolicyPath, string(regoContent)), + rego.Module(regoFile, string(regoContent)), rego.Input(inputMap), ) @@ -53,8 +63,19 @@ func ValidateInput(yamlContent string, regoPolicyPath string) error { return fmt.Errorf("error evaluating Rego: %v", err) } - if err := PrintResults(rs); err != nil { - return fmt.Errorf("error evaluating rego results fron policy %s: %v", regoPolicyPath, err) + // filePaths, err := FecthRegoMetadata(metadataDir, metaExt) + // if err != nil { + // return fmt.Errorf("error fetching metadata files:", err) + + // } + // Load metadata from JSON files + metas, err := LoadRegoMetadata(metaFiles) + if err != nil { + return fmt.Errorf("error loading policy metadata: %v", err) + } + + if err := PrintResults(rs, metas); err != nil { + return fmt.Errorf("error evaluating rego results for %s: %v", regoPolicyPath, err) } return nil } diff --git a/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.json b/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.json new file mode 100644 index 00000000..28000042 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.json @@ -0,0 +1,9 @@ +{ + "name": "DenyAdd", + "policy_file": "deny_add.rego", + "policy_name": "deny_add", + "severity": "High", + "Description": "Ensure that COPY is used instead of ADD in Dockerfiles", + "Benchmark": "CIS-4.9", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.rego b/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.rego new file mode 100644 index 00000000..46cb4487 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_add/deny_add.rego @@ -0,0 +1,10 @@ +package dockerfile_validation + + +import rego.v1 + +# # Ensure that COPY is used instead of ADD CIS 4.9 +deny_add contains msg if { + input[i].cmd != "add" + msg:= "Dockerfile does not use ADD instruction - CIS 4.9" +} \ No newline at end of file diff --git a/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.json b/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.json new file mode 100644 index 00000000..ba2a4436 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.json @@ -0,0 +1,9 @@ +{ + "name": "DenyCaching", + "policy_file": "deny_caching.rego", + "policy_name": "deny_caching", + "severity": "High", + "Description": "Ensure cache is invalidated in update instructions", + "Benchmark": "CIS-4.7", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.rego b/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.rego new file mode 100644 index 00000000..de40280a --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_caching/deny_caching.rego @@ -0,0 +1,15 @@ +package dockerfile_validation + + +import rego.v1 + + +# # Avoid using cached layers CIS 4.7 +deny_caching contains msg if { + input[i].cmd == "run" + val4:= input[i].value + matches := regex.match(".*?(apk|yum|dnf|apt|pip).+?(install|[dist-|check-|group]?up[grade|date]).*", val4) + matches == true + contains(val4, "--no-cache") + msg:= "Dockerfile invalidates cache when installing dependencies" +} \ No newline at end of file diff --git a/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.json b/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.json new file mode 100644 index 00000000..65fd655a --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.json @@ -0,0 +1,9 @@ +{ + "name": "DenyRootUser", + "policy_file": "deny_root_user.rego", + "policy_name": "deny_root_user", + "severity": "Critical", + "Description": "Ensure that the Dockerfile for the container image contains USER instruction", + "Benchmark": "CIS-4.1", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.rego b/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.rego new file mode 100644 index 00000000..56faa0f8 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_root_user/deny_root_user.rego @@ -0,0 +1,13 @@ +package dockerfile_validation + + +import rego.v1 + +# Do not use root user +deny_root_user contains msg if { + input[i].cmd == "user" + val2:= input[i].value + val2 != "root" + val2 != "0" + msg:= "Dockerfile does not support root user" +} diff --git a/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.json b/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.json new file mode 100644 index 00000000..1420570e --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.json @@ -0,0 +1,9 @@ +{ + "name": "DenySudo", + "policy_file": "deny_sudo.rego", + "policy_name": "deny_sudo", + "severity": "Critical", + "Description": "Ensure sudo is not used in RUN instructions", + "Benchmark": "CIS-4.1", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.rego b/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.rego new file mode 100644 index 00000000..650d05d0 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/deny_sudo/deny_sudo.rego @@ -0,0 +1,12 @@ +package dockerfile_validation + + +import rego.v1 + +# # Do not sudo +deny_sudo contains msg if { + input[i].cmd == "run" + val3:= input[i].value + not contains(val3, "sudo") + msg:= "Dockerfile does not support sudo" +} \ No newline at end of file diff --git a/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.json b/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.json new file mode 100644 index 00000000..c6783333 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.json @@ -0,0 +1,9 @@ +{ + "name": "UseChainguradImage", + "policy_file": "trusted_base_image.rego", + "policy_name": "trusted_base_image", + "severity": "High", + "Description": "Use hardened and secure base image from Chainguard", + "Benchmark": "CIS-4.2", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.rego b/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.rego new file mode 100644 index 00000000..32f9f504 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/trusted_base_image/trusted_base_image.rego @@ -0,0 +1,13 @@ +package dockerfile_validation + +import rego.v1 + +trusted_base_image contains result if { + input[i].cmd == "from" + val := split(input[i].value, "/") + val[0] == "cgr.dev" + result := { + "msg": "Dockerfile uses hardened base image from Chainguard", + "benchmark": "CIS - 4.2" + } +} \ No newline at end of file diff --git a/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.json b/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.json new file mode 100644 index 00000000..6377a127 --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.json @@ -0,0 +1,9 @@ +{ + "name": "UserDefined", + "policy_file": "user_defined.rego", + "policy_name": "user_defined", + "severity": "High", + "Description": "Ensure that a user for the container has been created", + "Benchmark": "CIS-4.1", + "Category": "Infrastructure security" +} diff --git a/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.rego b/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.rego new file mode 100644 index 00000000..2a627a6d --- /dev/null +++ b/templates/defaultpolicies/rego/docker_policies/user_defined/user_defined.rego @@ -0,0 +1,11 @@ +package dockerfile_validation + + +import rego.v1 + + +# CIS 4.1 Ensure that a user for the container has been created +user_defined contains msg if{ + input[i].cmd == "user" + msg:= "Ensure that a user for the container has been created" +} \ No newline at end of file diff --git a/templates/defaultpolicies/rego/dockerfile_policies.rego b/templates/defaultpolicies/rego/dockerfile_policies.rego index 1eb92e1d..bd62c330 100644 --- a/templates/defaultpolicies/rego/dockerfile_policies.rego +++ b/templates/defaultpolicies/rego/dockerfile_policies.rego @@ -4,7 +4,7 @@ package dockerfile_validation import rego.v1 -untrusted_base_image contains msg if { +trusted_base_image contains msg if { input[i].cmd == "from" val := split(input[i].value, "/") val[0] == "cgr.dev"