Kubescape's CEL (Common Expression Language) runtime threat detection rules library. This repository contains a collection of security rules that can be used for runtime threat detection in Kubernetes environments.
The rule library provides a structured way to define security rules using YAML format. Each rule is defined as a Custom Resource Definition (CRD) instance that can be deployed to Kubernetes clusters for runtime threat detection.
Each rule is defined in a YAML file with the following structure:
apiVersion: kubescape.io/v1
kind: Rules
metadata:
name: rule-name-rule
namespace: kubescape
labels:
app: kubescape
spec:
rules:
- name: "Rule Display Name"
enabled: true
id: "R####"
description: "Description of what the rule detects"
expressions:
message: "CEL expression for alert message"
uniqueId: "CEL expression for unique identifier"
ruleExpression:
- eventType: "eventType_name"
expression: "CEL expression for detection logic"
profileDependency: 0 # 0=Required, 1=Optional, 2=NotRequired
severity: 1
supportPolicy: false
tags:
- "tag1"
- "tag2"| Field | Type | Description | Required |
|---|---|---|---|
name |
string | Human-readable rule name | Yes |
enabled |
boolean | Whether the rule is active | Yes |
id |
string | Unique rule identifier (format: R####) | Yes |
description |
string | Detailed description of the rule | Yes |
expressions.message |
string | CEL expression for alert message | Yes |
expressions.uniqueId |
string | CEL expression for unique event ID | Yes |
expressions.ruleExpression |
array | Array of detection expressions | Yes |
profileDependency |
integer | Profile dependency level (0,1,2) | Yes |
severity |
integer | Rule severity level | Yes |
supportPolicy |
boolean | Whether rule supported by rule policy | Yes |
tags |
array | Array of tags for categorization | Yes |
state |
object | Rule state | No |
exec- Process execution eventsopen- File access eventscapabilities- Linux capability eventsdns- DNS query eventsnetwork- Network connection eventssyscall- System call eventsrandomx- XMRig mining eventssymlink- Symbolic link eventshardlink- Hard link eventsssh- SSH connection eventshttp- HTTP request eventsptrace- Process tracing eventsiouring- IO_uring eventsfork- Process fork eventsexit- Process exit eventsprocfs- Proc filesystem events
Create a new directory in pkg/rules/ with the naming convention:
r####-descriptive-name/
Example:
pkg/rules/r0001-unexpected-process-launched/
Create a YAML file in your rule directory with the rule definition (see example unexpected-process-launched.yaml)
Create a rule_test.go file in your rule directory (see example rule_test.go)
Run the tests to ensure your rule works correctly:
go test -v ./pkg/rules/r0001-unexpected-process-launched/The gen.sh script automatically combines all individual rule YAML files into a single CRD instance. The
recommended entrypoint is the Make target below, which wraps the script.
make generate-rules-crd- Scans the
pkg/rules/directory for all YAML files - Combines all individual rule definitions into a single Rule instance
- Generates
rules-crd.yamlwith all rules in the spec array - Validates the generated YAML (if
yqis available)
The script generates rules-crd.yaml containing:
apiVersion: kubescape.io/v1
kind: Rules
metadata:
name: kubescape-rules
namespace: kubescape
labels:
app: kubescape
spec:
rules:
- name: "Rule 1"
# ... rule 1 definition
- name: "Rule 2"
# ... rule 2 definition
# ... all other rulesbashshellyq(optional, for YAML validation)
- Create a new rule following the directory structure and naming conventions
- Write the rule YAML with proper CEL expressions
- Add comprehensive tests in
rule_test.go - Test your rule with
go test -v ./pkg/rules/your-rule/ - Generate the combined CRD with
make generate-rules-crd - Deploy the generated
rules-crd.yamlto your Kubernetes cluster
go test -v ./pkg/rules/...go test -v ./pkg/rules/r0001-unexpected-process-launched/make generate-rules-crd
# Check the generated rules-crd.yaml fileRules use Common Expression Language (CEL) for expressions. Key concepts:
Defines the alert message format:
"'Unexpected process launched: ' + event.Comm + ' with PID ' + string(event.Pid)"
Creates a unique identifier for deduplication:
"event.Comm + '_' + string(event.Pid) + '_' + event.ExePath"
Defines the detection logic:
"!data.profile_checks.exec_path"
- Use descriptive names for rules and directories
- Follow the ID numbering convention (R####)
- Write comprehensive tests for each rule
- Use appropriate tags for categorization
- Set correct severity levels based on impact
- Document complex CEL expressions with comments
- Test both positive and negative scenarios
- Validate generated YAML before deployment
When a rule's profileDependency is Required (0) or Optional (1), it must declare
profileDataRequired listing which profile surfaces the rule queries at runtime. Look at
every CEL guard that passes an event field to a profile helper (ap.* / nn.*) and
translate the argument into a pattern under the correct surface key:
| Event field | Surface key |
|---|---|
event.path / event.exepath (open events) |
opens |
event.path / event.exepath (exec events) |
execs |
event.syscallName |
syscalls |
event.capName |
capabilities |
event.name (DNS) |
egressDomains |
event.dstAddr / event.dstIp (network) |
egressAddresses |
event.endpoint (HTTP) |
endpoints |
| Guard operator | Pattern type |
|---|---|
== |
exact |
.startsWith(...) |
prefix |
.endsWith(...) |
suffix |
.contains(...) |
contains |
If the helper receives a fully dynamic argument with no co-located literal guard, declare
the surface as all.
Example:
profileDependency: 0
profileDataRequired:
opens:
- exact: "/var/run/docker.sock"
- prefix: "/etc/cron.d/"
execs: allThe lint at cmd/lint-projection/ enforces that declarations are present and schema-valid.
Run it locally with make lint-projection. Getting the patterns right is the rule author's
responsibility — runtime metrics in node-agent catch drift after deployment.
Rules with profileDependency: 2 (NotRequired) must not declare profileDataRequired;
the lint emits a warning if they do.
- Fork the repository
- Create a feature branch
- Add your rule following the guidelines
- Write comprehensive tests
- Run the generation script
- Submit a pull request