Skip to content

Commit

Permalink
ci: add lint for checks metadata
Browse files Browse the repository at this point in the history
Signed-off-by: Nikita Pivkin <nikita.pivkin@smartforce.io>
  • Loading branch information
nikpivkin authored and simar7 committed Jan 29, 2025
1 parent 0afa905 commit ba50e6a
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .regal/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ rules:
- pattern: '^builtin|lib|defsec|appshield'
targets:
- package
invalid-metadata:
level: error
naming:
deny-rule:
level: error
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# METADATA
# description: |
# Ensures that metadata definitions adhere to the required schema by validating the following:
# - Ensure all necessary fields are present in metadata.
# - Detect and report any unexpected or forbidden fields.
# - Validate that field values are compliant with the expected format or constraints.
# schemas:
# - input: schema.regal.ast
package custom.regal.rules.custom["invalid-metadata"]

import rego.v1

import data.regal.ast
import data.regal.result

report contains _violation_check(lib_metadata_schema) if _is_lib_package

report contains _violation_check(check_metadata_schema) if not _is_lib_package

_is_lib_package if input["package"].path[1].value == "lib"

_violation_check(schema) := violation if {
some annot in input["package"].annotations
annot.scope == "package"

[match, errors] := json.match_schema(annot.custom, schema)
not match

error_messages := [err.error | some err in errors]

violation := result.fail(
rego.metadata.chain(),
object.union(
result.location(annot),
{"description": concat("\n", error_messages)},
),
)
}

lib_metadata_schema := {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"library": {"type": "boolean"},
"input": input_schema,
},
"required": ["library"],
"additionalProperties": false,
}

check_metadata_schema := {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {"type": "string"},
"avd_id": {"type": "string"},
"provider": {"type": "string"},
"service": {"type": "string"},
"short_code": {"type": "string"},
"severity": {
"type": "string",
"enum": ["LOW", "MEDIUM", "HIGH", "CRITICAL"],
},
"input": input_schema,
"frameworks": {"type": "object"},
"deprecated": {"type": "boolean"},
"examples": {"type": "string"},
"aliases": {
"type": "array",
"items": {"type": "string"},
},
"cloud_formation": {"$ref": "#/$defs/engine_metadata"},
"terraform": {"$ref": "#/$defs/engine_metadata"},
"recommended_actions": {"type": "string"},
"recommended_action": {"type": "string"},
},
"required": ["id", "avd_id"],
"additionalProperties": false,
"anyOf": [
{"required": ["recommended_actions"]},
{"required": ["recommended_action"]},
{"not": {"required": ["recommended_actions", "recommended_action"]}},
],
"$defs": {"engine_metadata": {
"type": "object",
"properties": {
"good_examples": {"type": "string"},
"bad_examples": {"type": "string"},
"links": {
"type": "array",
"items": {
"type": "string",
"format": "uri",
},
},
},
"additionalProperties": false,
}},
}

input_schema := {
"type": "object",
"properties": {"selector": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {"type": "string"},
"subtypes": {
"type": "array",
"items": {
"type": "object",
"oneOf": [
{
"properties": {"kind": {"type": "string"}},
"required": ["kind"],
"additionalProperties": false,
},
{
"properties": {
"provider": {"type": "string"},
"service": {"type": "string"},
},
"required": ["service", "provider"],
"additionalProperties": false,
},
],
},
},
},
"required": ["type"],
"additionalProperties": false,
},
}},
"additionalProperties": false,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package custom.regal.rules.custom["invalid-metadata_test"]

import rego.v1

import data.custom.regal.rules.custom["invalid-metadata"] as rule

test_invalid_metadata if {
module := regal.parse_module("example.rego", `
# METADATA
# title: test title
# description: test description
# schemas:
# - input: schema["kubernetes"]
# custom:
# id: TEST-001
# avdid: AVD-TEST-001
# examples: test/ff.json
package policy
foo := true`)

r := rule.report with input as module

r == {{
"category": "custom",
"description": "(Root): avd_id is required\n(Root): Additional property avdid is not allowed",
"level": "error",
"location": {
"col": 1,
"end": {
"col": 27,
"row": 10,
},
"file": "example.rego",
"row": 2,
"text": "# METADATA",
},
"title": "invalid-metadata",
}}
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test-rego:

.PHONY: check-rego
check-rego:
go run ./cmd/opa check lib checks --v0-v1 --strict
@go run ./cmd/opa check lib checks --v0-v1 --strict

.PHONY: lint-rego
lint-rego: check-rego
Expand Down
2 changes: 1 addition & 1 deletion checks/cloud/aws/iam/no_policy_wildcards.rego
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document
# good_examples: checks/cloud/aws/iam/no_policy_wildcards.yaml
# bad_examples: checks/cloud/aws/iam/no_policy_wildcards.yaml
# cloudformation:
# cloud_formation:
# good_examples: checks/cloud/aws/iam/no_policy_wildcards.yaml
# bad_examples: checks/cloud/aws/iam/no_policy_wildcards.yaml
package builtin.aws.iam.aws0057
1 change: 0 additions & 1 deletion checks/docker/apt_get_missing_no_install_recommends.rego
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# schemas:
# - input: schema["dockerfile"]
# custom:
# schema_version: 1
# id: DS029
# avd_id: AVD-DS-0029
# severity: HIGH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# schemas:
# - input: schema["dockerfile"]
# custom:
# schema_version: 1
# id: DS021
# avd_id: AVD-DS-0021
# severity: HIGH
Expand Down
2 changes: 1 addition & 1 deletion checks/kubernetes/general/manage_namespace_secrets.rego
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# custom:
# id: KSV113
# avd_id: AVD-KSV-0113
# severity: Medium
# severity: MEDIUM
# short_code: no-manage-ns-secrets
# recommended_actions: "Manage namespace secrets are not allowed. Remove resource 'secrets' from role"
# input:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# custom:
# id: KSV114
# avd_id: AVD-KSV-0114
# severity: Critical
# severity: CRITICAL
# short_code: no-manage-webhook
# recommended_actions: "Remove webhook configuration resouces/verbs, acceptable values for verbs ['get', 'list', 'watch']"
# input:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# custom:
# id: KSV002
# avd_id: AVD-KSV-0002
# severity: Low
# severity: LOW
# short_code: use-default-apparmor-profile
# recommended_action: "set the 'runtime/default' value from 'container.apparmor.security.beta.kubernetes.io'."
# input:
Expand Down

0 comments on commit ba50e6a

Please sign in to comment.