Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Regal linting in CI pipeline #515

Merged
merged 1 commit into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions .github/workflows/pr-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
with:
use-verbose-mode: 'yes'

# main job of testing and building the env.
# main job of testing and building the env.
test_pr_checks:
# needs: [markdown-link-check]
permissions:
Expand All @@ -42,10 +42,10 @@ jobs:
# needs: [test_pr_checks]
# uses: kubescape/workflows/.github/workflows/coverage-check.yaml@main
# if: |
# ${{ (always() &&
# (contains(needs.*.result, 'success')) &&
# !(contains(needs.*.result, 'skipped')) &&
# !(contains(needs.*.result, 'failure')) &&
# ${{ (always() &&
# (contains(needs.*.result, 'success')) &&
# !(contains(needs.*.result, 'skipped')) &&
# !(contains(needs.*.result, 'failure')) &&
# !(contains(needs.*.result, 'cancelled'))) }}
# with:
# COVERAGELIMIT: "58"
Expand All @@ -70,7 +70,7 @@ jobs:
name: checkout repo content
with:
token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

# Test using Golang OPA hot rule compilation
- name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568
Expand All @@ -84,12 +84,20 @@ jobs:
apt update && apt install -y cmake
GOPATH=$(go env GOPATH) make

- name: Set up Regal
uses: StyraInc/[email protected]
with:
version: v0.10.1

- name: Lint Rego
run: regal lint --format github rules

- name: setup python
uses: actions/setup-python@v4
with:
python-version: 3.10.6

# validate control-ID duplications
# validate control-ID duplications
- run: python ./scripts/validations.py

# generating subsections ids
Expand Down Expand Up @@ -117,7 +125,7 @@ jobs:
path: ${{ env.REGO_ARTIFACT_PATH }}/
if-no-files-found: error

# test kubescape with regolibrary artifacts
# test kubescape with regolibrary artifacts
ks-and-rego-test:
uses: kubescape/workflows/.github/workflows/kubescape-cli-e2e-tests.yaml@main
if: |
Expand Down Expand Up @@ -145,7 +153,7 @@ jobs:
]'
DOWNLOAD_ARTIFACT_PATH: ${{ needs.build-and-rego-test.outputs.REGO_ARTIFACT_PATH }}
secrets: inherit

clean-up:
name: Remove pre-release folder and clean up
runs-on: ubuntu-latest
Expand Down
12 changes: 12 additions & 0 deletions rules/.regal/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ rules:
# This should be enabled, but the version of OPA used here is
# too old to recognize the object.keys built-in function
level: ignore
no-defined-entrypoint:
level: ignore
use-some-for-output-vars:
level: ignore
imports:
prefer-package-imports:
level: ignore
style:
avoid-get-and-list-prefix:
level: ignore
Expand All @@ -15,6 +22,11 @@ rules:
level: ignore
prefer-snake-case:
level: ignore
prefer-some-in-iteration:
level: ignore
rule-length:
level: error
max-rule-length: 50
todo-comment:
level: ignore
use-assignment-operator:
Expand Down
8 changes: 4 additions & 4 deletions rules/CVE-2021-25742/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ deny[msga] {
is_tag_image(image)

# Extracting version from image tag
tag_version_match := regex.find_all_string_submatch_n("[0-9]+\\.[0-9]+\\.[0-9]+", image, -1)[0][0]
tag_version_match := regex.find_all_string_submatch_n(`[0-9]+\.[0-9]+\.[0-9]+`, image, -1)[0][0]
image_version_str_arr := split(tag_version_match,".")
image_version_arr := [to_number(image_version_str_arr[0]),to_number(image_version_str_arr[1]),to_number(image_version_str_arr[2])]

# Check if vulnerable
# Check if vulnerable
is_vulnerable(image_version_arr, deployment.metadata.namespace)

path := sprintf("spec.template.spec.containers[%v].image", [format_int(i, 10)])
Expand All @@ -25,7 +25,7 @@ deny[msga] {
}
}


is_nginx_image(image) {
contains(image, "nginx-controller")
}
Expand Down Expand Up @@ -57,7 +57,7 @@ is_vulnerable(image_version, namespace) {
image_version[2] == 0
is_allow_snippet_annotation_on(namespace)
}

is_vulnerable(image_version, namespace) {
image_version[0] == 1
image_version[1] == 0
Expand Down
8 changes: 4 additions & 4 deletions rules/CVE-2022-0185/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package armo_builtins
deny[msga] {
node := input[_]
node.kind == "Node"
kernel_version_match := regex.find_all_string_submatch_n("[0-9]+\\.[0-9]+\\.[0-9]+", node.status.nodeInfo.kernelVersion, -1)
kernel_version_match := regex.find_all_string_submatch_n(`[0-9]+\.[0-9]+\.[0-9]+`, node.status.nodeInfo.kernelVersion, -1)
kernelVersion := kernel_version_match[0][0]

kernel_version_arr := split(kernelVersion, ".")
to_number(kernel_version_arr[0]) == 5
to_number(kernel_version_arr[1]) >= 1
to_number(kernel_version_arr[1]) <= 16
to_number(kernel_version_arr[2]) < 2
to_number(kernel_version_arr[2]) < 2

node.status.nodeInfo.operatingSystem == "linux"
path := "status.nodeInfo.kernelVersion"

Expand Down
2 changes: 1 addition & 1 deletion rules/K8s common labels usage/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ deny[msga] {
}
}

#handles cronjob
# handles cronjob
deny[msga] {
wl := input[_]
wl.kind == "CronJob"
Expand Down
4 changes: 2 additions & 2 deletions rules/alert-any-hostpath/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ deny[msga] {
}
}

#handles majority of workload resources
# handles majority of workload resources
deny[msga] {
wl := input[_]
spec_template_spec_patterns := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
Expand All @@ -48,7 +48,7 @@ deny[msga] {
}
}

#handles CronJobs
# handles CronJobs
deny[msga] {
wl := input[_]
wl.kind == "CronJob"
Expand Down
10 changes: 5 additions & 5 deletions rules/alert-rw-hostpath/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ deny[msga] {
}
}

#handles majority of workload resources
# handles majority of workload resources
deny[msga] {
wl := input[_]
spec_template_spec_patterns := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
Expand All @@ -57,11 +57,11 @@ deny[msga] {
"alertObject": {
"k8sApiObjects": [wl]
}

}
}

#handles CronJobs
# handles CronJobs
deny[msga] {
wl := input[_]
wl.kind == "CronJob"
Expand All @@ -73,7 +73,7 @@ deny[msga] {
volume_mount := container.volumeMounts[k]
volume_mount.name == volume.name
beggining_of_path := "spec.jobTemplate.spec.template.spec."
result := is_rw_mount(volume_mount, beggining_of_path, i, k)
result := is_rw_mount(volume_mount, beggining_of_path, i, k)
failed_path := get_failed_path(result)
fixed_path := get_fixed_path(result)

Expand Down Expand Up @@ -112,4 +112,4 @@ is_rw_mount(mount, beggining_of_path, i, k) = [failed_path, fix_path] {
mount.readOnly == false
failed_path = sprintf("%vcontainers[%v].volumeMounts[%v].readOnly", [beggining_of_path, format_int(i, 10), format_int(k, 10)])
fix_path = ""
}
}
2 changes: 1 addition & 1 deletion rules/anonymous-requests-to-kubelet-updated/raw.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package armo_builtins

#CIS 4.2.1 https://workbench.cisecurity.org/sections/1126668/recommendations/1838638
# CIS 4.2.1 https://workbench.cisecurity.org/sections/1126668/recommendations/1838638

deny[msga] {
obj := input[_]
Expand Down
10 changes: 5 additions & 5 deletions rules/audit-policy-content/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ deny[msga] {
}

# Sample rules object
#rules:
# - level: RequestResponse
# resources:
# - group: ""
# resources: ["pods"]
# rules:
# - level: RequestResponse
# resources:
# - group: ""
# resources: ["pods"]
are_audit_file_rules_valid(rules) if {
seeked_resources_with_audit_level := {
"secrets": {
Expand Down
1 change: 1 addition & 0 deletions rules/cluster-admin-role/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package armo_builtins
import future.keywords.in

# returns subjects with cluster admin role
# regal ignore:rule-length
deny[msga] {
subjectVector := input[_]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package armo_builtins

#CIS 4.2.3 https://workbench.cisecurity.org/sections/1126668/recommendations/1838643
# CIS 4.2.3 https://workbench.cisecurity.org/sections/1126668/recommendations/1838643

deny[msga] {
obj := input[_]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ deny[msga] {
policies.kind == "PolicyVersion"
policies.metadata.provider == "eks"

#node_instance_role_policies := ["arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"]
# node_instance_role_policies := ["arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"]
some policy in node_instance_role_policies
some stat, _ in policies.data.policiesDocuments[policy].Statement
not isPolicyCompliant(policies, policy, stat)
Expand Down
4 changes: 2 additions & 2 deletions rules/etcd-unique-ca/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package armo_builtins

import future.keywords.in

#CIS 2.7 https://workbench.cisecurity.org/sections/1126654/recommendations/1838578
# CIS 2.7 https://workbench.cisecurity.org/sections/1126654/recommendations/1838578

deny[msga] {
etcdPod := [pod | pod := input[_]; filter_input(pod, "etcd")]
Expand Down Expand Up @@ -39,7 +39,7 @@ filter_input(obj, res) {
}

get_argument_value(command, argument) = value {
args := regex.split("=", command)
args := split(command, "=")
some i, sprintf("%v", [argument]) in args
value := args[i + 1]
}
Expand Down
7 changes: 4 additions & 3 deletions rules/exposed-critical-pods/filter.rego
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package armo_builtins

# regal ignore:rule-length
deny[msga] {
services := [ x | x = input[_]; x.kind == "Service" ]
pods := [ x | x = input[_]; x.kind == "Pod" ]
Expand All @@ -9,8 +10,8 @@ deny[msga] {
service := services[_]
vuln := vulns[_]

# vuln data is relevant
count(vuln.data) > 0
# vuln data is relevant
count(vuln.data) > 0

# service is external-facing
filter_external_access(service)
Expand All @@ -33,7 +34,7 @@ deny[msga] {
"namespace": pod.metadata.namespace
}

external_objects = {
external_objects = {
"apiVersion": "result.vulnscan.com/v1",
"kind": pod.kind,
"metadata": metadata,
Expand Down
9 changes: 5 additions & 4 deletions rules/exposed-critical-pods/raw.rego
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package armo_builtins

# regal ignore:rule-length
deny[msga] {
services := [ x | x = input[_]; x.kind == "Service" ]
pods := [ x | x = input[_]; x.kind == "Pod" ]
Expand All @@ -9,8 +10,8 @@ deny[msga] {
service := services[_]
vuln := vulns[_]

# vuln data is relevant
count(vuln.data) > 0
# vuln data is relevant
count(vuln.data) > 0

# service is external-facing
filter_external_access(service)
Expand All @@ -22,7 +23,7 @@ deny[msga] {
container := pod.spec.containers[i]

# image has vulnerabilities

container.image == vuln.metadata.name

# At least one critical vulnerabilities
Expand All @@ -37,7 +38,7 @@ deny[msga] {
"namespace": pod.metadata.namespace
}

external_objects = {
external_objects = {
"apiVersion": "result.vulnscan.com/v1",
"kind": pod.kind,
"metadata": metadata,
Expand Down
9 changes: 5 additions & 4 deletions rules/exposed-rce-pods/filter.rego
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package armo_builtins


# regal ignore:rule-length
deny[msga] {
services := [ x | x = input[_]; x.kind == "Service" ; x.apiVersion == "v1"]
pods := [ x | x = input[_]; x.kind == "Pod" ; x.apiVersion == "v1"]
Expand All @@ -9,8 +10,8 @@ deny[msga] {
service := services[_]
vuln := vulns[_]

# vuln data is relevant
count(vuln.data) > 0
# vuln data is relevant
count(vuln.data) > 0

# service is external-facing
filter_external_access(service)
Expand All @@ -33,7 +34,7 @@ deny[msga] {
"namespace": pod.metadata.namespace
}

external_objects = {
external_objects = {
"apiVersion": "result.vulnscan.com/v1",
"kind": pod.kind,
"metadata": metadata,
Expand Down
Loading