Skip to content

Commit ff3c8a1

Browse files
committed
Document CEL Rules and its usage
1 parent 67e92d2 commit ff3c8a1

4 files changed

Lines changed: 638 additions & 0 deletions

File tree

.claude/CLAUDE.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,109 @@ template:
158158
pkgname@ubuntu2204: avahi-daemon # Platform-specific overrides
159159
```
160160

161+
## CEL Rules (Kubernetes/OpenShift)
162+
163+
CEL (Common Expression Language) rules provide native Kubernetes resource evaluation without requiring shell access or OVAL checks. CEL rules are used by the compliance-operator for Kubernetes and OpenShift compliance scanning.
164+
165+
**Important:** CEL rules are **excluded** from XCCDF/OVAL DataStreams and are generated as a separate `${PRODUCT}-cel-content.yaml` file.
166+
167+
### Required Fields for CEL Rules
168+
169+
```yaml
170+
documentation_complete: true
171+
172+
title: 'Rule Title'
173+
174+
description: |-
175+
Description of what the rule checks.
176+
177+
rationale: |-
178+
Why this rule matters.
179+
180+
severity: medium
181+
182+
scannerType: CEL # REQUIRED: Marks this as a CEL rule
183+
184+
checkType: Platform # Usually Platform for K8s checks
185+
186+
expression: |- # REQUIRED: CEL expression (must evaluate to boolean)
187+
resource.spec.enabled == true
188+
189+
inputs: # REQUIRED: Kubernetes resources to evaluate
190+
- name: resource
191+
kubernetesInputSpec:
192+
apiVersion: v1
193+
resource: pods
194+
resourceName: my-pod # Optional: specific resource
195+
resourceNamespace: default # Optional: specific namespace
196+
197+
ocil: |- # Optional: Manual check instructions
198+
Run the following command:
199+
<pre>$ oc get pods</pre>
200+
201+
failureReason: |- # Optional: Custom failure message
202+
The resource is not properly configured.
203+
204+
references: # Optional: Same as regular rules
205+
cis@ocp4: 1.2.3
206+
nist: CM-6
207+
```
208+
209+
### CEL Expression Examples
210+
211+
Simple boolean check:
212+
```yaml
213+
expression: resource.spec.enabled == true
214+
```
215+
216+
Check for field absence:
217+
```yaml
218+
expression: !has(resource.spec.insecureField)
219+
```
220+
221+
Multiple conditions:
222+
```yaml
223+
expression: |-
224+
resource.spec.replicas >= 3 &&
225+
has(resource.spec.securityContext) &&
226+
resource.spec.securityContext.runAsNonRoot == true
227+
```
228+
229+
### CEL Profile Format
230+
231+
Profiles that use CEL rules must have `scannerType: CEL`:
232+
233+
```yaml
234+
documentation_complete: true
235+
236+
title: 'CIS VM Extension Benchmark'
237+
238+
description: |-
239+
Profile description.
240+
241+
scannerType: CEL # REQUIRED: Marks this as a CEL profile
242+
243+
selections:
244+
- kubevirt-nonroot-feature-gate-is-enabled
245+
- kubevirt-no-permitted-host-devices
246+
```
247+
248+
**Note:** CEL profiles can only select CEL rules and are excluded from XCCDF generation.
249+
250+
**Important:** Use hyphens rule IDs (Kubernetes naming convention), not underscores.
251+
252+
### Enabling CEL Content for a Product
253+
254+
In `products/${PRODUCT}/CMakeLists.txt`:
255+
256+
```cmake
257+
set(PRODUCT "ocp4")
258+
set(PRODUCT_CEL_ENABLED TRUE) # Enable CEL content generation
259+
ssg_build_product(${PRODUCT})
260+
```
261+
262+
See `docs/manual/developer/12_cel_content.md` for complete CEL documentation.
263+
161264
## Common Jinja2 Macros
162265

163266
Used in rule descriptions, OCIL, fixtext, and warnings fields:

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ profiles. These are meant to be run on machines to put them into
4141
compliance. We recommend using other formats but understand that for
4242
some deployment scenarios bash is the only option.
4343

44+
*"CEL content"* refers to compliance content using the Common Expression Language (CEL)
45+
for Kubernetes and OpenShift platforms. CEL content is generated as YAML files and is
46+
designed for native Kubernetes resource evaluation through the compliance-operator,
47+
without requiring shell access to nodes. This format is used for platform-level
48+
compliance checks on container orchestration systems.
49+
4450
### Why?
4551

4652
We want multiple organizations to be able to efficiently develop security

docs/manual/developer/07_understanding_build_system.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ of occurrence:
8383
- Load resolved rules, profiles, groups, collected remediations and the unlinked OVAL document and generate XCCDF, OVAL and OCIL documents from this data.
8484
- Generate CPE OVAL and CPE dictionary.
8585
- Combining the OVAL, OCIL, CPE and XCCDF documents into a single SCAP source data stream.
86+
- Generate CEL content YAML for Kubernetes/OpenShift compliance checks (if enabled for the product).
8687
- Generate content for derived products (such as CentOS and Scientific Linux).
8788
- Generate HTML tables, Bash scripts, Ansible Playbooks and other secondary artifacts.
8889

@@ -93,6 +94,9 @@ refer to their help text for more information and usage:
9394

9495
- `build_all_guides.py` -- generates separate HTML guides for every profile
9596
in an XCCDF document.
97+
- `build_cel_content.py` -- generates CEL (Common Expression Language) content
98+
YAML for Kubernetes/OpenShift compliance checks. See [CEL Content](12_cel_content.md)
99+
for detailed information about CEL rules and profiles.
96100
- `build_rule_playbooks.py` -- generates per-rule per-profile playbooks in
97101
Ansible content.
98102
- `build_sce.py` -- outputs SCE content and combined metadata.
@@ -167,3 +171,95 @@ Steps to link an OVAL document to an XCCDF document:
167171
8. The OVAL Document object is stored as an XML file `build/ssg-${PRODUCT}-oval.xml`.
168172
9. For each XCCDF rule, a minimal OVAL Documents document is generated as an artifact
169173
10. For each reference of OVAL check in XCCDF, a link to the `check-content` and a `check-export` element is added.
174+
175+
## How CEL Content is Built
176+
177+
CEL (Common Expression Language) content provides an alternative scanning mechanism to OVAL specifically designed for Kubernetes and OpenShift API resource evaluation. Unlike OVAL which requires shell access and evaluates system state, CEL rules evaluate Kubernetes resources directly through the API server.
178+
179+
CEL content generation is optional and must be explicitly enabled for each product.
180+
181+
### Enabling CEL Content
182+
183+
CEL content generation is enabled by setting `PRODUCT_CEL_ENABLED` in the product's `CMakeLists.txt`:
184+
185+
```cmake
186+
set(PRODUCT "ocp4")
187+
set(PRODUCT_REMEDIATION_LANGUAGES "ignition;kubernetes")
188+
set(PRODUCT_CEL_ENABLED TRUE)
189+
190+
ssg_build_product(${PRODUCT})
191+
```
192+
193+
### Build Process
194+
195+
When CEL content is enabled for a product, the build system performs the following steps:
196+
197+
1. **Rule and Profile Resolution** - All rules and profiles are compiled to their product-specific resolved form (same as for XCCDF/OVAL).
198+
199+
2. **CEL Rule Loading** - The `build_cel_content.py` script loads all rules with `scannerType: CEL` from the `build/${PRODUCT}/rules/` directory.
200+
201+
3. **CEL Profile Loading** - The script loads all profiles with `scannerType: CEL` from the `build/${PRODUCT}/profiles/` directory.
202+
203+
4. **Validation** - The build system validates CEL content:
204+
- Rules must have `expression` field (non-empty CEL expression)
205+
- Rules must have `inputs` field (non-empty list of Kubernetes resources)
206+
- Profiles must have `selected` field with at least one rule
207+
- No duplicate rule names (after conversion to hyphenated format)
208+
- All profile rule references must exist in the CEL rules
209+
210+
5. **Content Generation** - The script generates a single CEL content YAML file at `build/${PRODUCT}-cel-content.yaml`.
211+
212+
### CEL Content Structure
213+
214+
The generated CEL content YAML has two main sections:
215+
216+
```yaml
217+
profiles:
218+
- id: cis_vm_extension # Profile ID (with underscores)
219+
name: cis-vm-extension # Profile name (with hyphens)
220+
title: Profile Title
221+
description: Profile description
222+
productType: Platform
223+
rules: # List of rule names (hyphenated)
224+
- rule-name-one
225+
- rule-name-two
226+
227+
rules:
228+
- id: rule_name_one # Rule ID (with underscores)
229+
name: rule-name-one # Rule name (with hyphens)
230+
title: Rule Title
231+
description: Rule description
232+
rationale: Rule rationale
233+
severity: medium
234+
checkType: Platform
235+
expression: | # CEL expression
236+
resource.spec.enabled == true
237+
inputs: # Kubernetes resource inputs
238+
- name: resource
239+
kubernetesInputSpec:
240+
apiVersion: v1
241+
resource: pods
242+
instructions: Manual check steps # From ocil field
243+
controls: # From references field
244+
cis@ocp4:
245+
- 1.2.3
246+
nist:
247+
- CM-6
248+
```
249+
250+
### Differences from XCCDF/OVAL
251+
252+
CEL content is processed differently from traditional XCCDF/OVAL content:
253+
254+
| Aspect | XCCDF/OVAL | CEL Content |
255+
|--------|-----------|-------------|
256+
| **Rules Included** | All rules except CEL | Only CEL rules |
257+
| **Profiles Included** | All profiles except CEL | Only CEL profiles |
258+
| **Output Format** | XML (DataStream) | YAML |
259+
| **Output Location** | `build/ssg-${PRODUCT}-ds.xml` | `build/${PRODUCT}-cel-content.yaml` |
260+
| **Scanner** | OpenSCAP | compliance-operator |
261+
| **Evaluation** | Shell commands, file checks | Kubernetes API queries |
262+
263+
Rules and profiles with `scannerType: CEL` are **excluded** from XCCDF/OVAL generation and **only** appear in the CEL content YAML.
264+
265+
For detailed information about creating CEL rules and profiles, see [CEL Content](12_cel_content.md).

0 commit comments

Comments
 (0)