@@ -158,6 +158,122 @@ template:
158158 pkgname@ubuntu2204: avahi-daemon # Platform-specific overrides
159159` ` `
160160
161+ # # CEL Checking Engine (Kubernetes/OpenShift)
162+
163+ CEL (Common Expression Language) provides native Kubernetes resource evaluation without requiring shell access or OVAL checks. Rules using the CEL checking engine are used by the compliance-operator for Kubernetes and OpenShift compliance scanning.
164+
165+ **Important:** Rules with CEL checks are **excluded** from SCAP data streams and are generated as a separate `${PRODUCT}-cel-content.yaml` file.
166+
167+ # ## Rule Structure for CEL Checks
168+
169+ Rules using CEL checks use a **split-file structure** to separate metadata from CEL-specific content :
170+
171+ - **`rule.yml`** - Contains metadata (title, description, rationale, severity, references, etc.)
172+ - **`cel/shared.yml`** - Contains CEL-specific fields (check_type, inputs, expression)
173+
174+ This allows rules to support **both CEL and OVAL** checks during migration from OVAL to CEL.
175+
176+ **Example rule.yml:**
177+ ` ` ` yaml
178+ documentation_complete: true
179+
180+ title: 'Rule Title'
181+
182+ description: |-
183+ Description of what the rule checks.
184+
185+ rationale: |-
186+ Why this rule matters.
187+
188+ severity: medium
189+
190+ ocil: |- # Optional: Manual check instructions
191+ Run the following command:
192+ <pre>$ oc get pods</pre>
193+
194+ references: # Optional: Same as regular rules
195+ cis@ocp4: 1.2.3
196+ nist: CM-6
197+ ` ` `
198+
199+ **Example cel/shared.yml:**
200+ ` ` ` yaml
201+ check_type: Platform # Usually Platform for K8s checks
202+
203+ failure_reason: |- # Optional: Custom failure message
204+ The resource is not properly configured.
205+
206+ expression: |- # REQUIRED: CEL expression (must evaluate to boolean)
207+ resource.spec.enabled == true
208+
209+ inputs: # REQUIRED: Kubernetes resources to evaluate
210+ - name: resource
211+ kubernetes_input_spec:
212+ api_version: v1
213+ resource: pods
214+ resource_name: my-pod # Optional: specific resource
215+ resource_namespace: default # Optional: specific namespace
216+ ` ` `
217+
218+ **Note:** The build system automatically detects rules with CEL checks by the presence of the `cel/` directory.
219+
220+ # ## CEL Expression Examples
221+
222+ Simple boolean check :
223+ ` ` ` yaml
224+ expression: resource.spec.enabled == true
225+ ` ` `
226+
227+ Check for field absence :
228+ ` ` ` yaml
229+ expression: !has(resource.spec.insecureField)
230+ ` ` `
231+
232+ Multiple conditions :
233+ ` ` ` yaml
234+ expression: |-
235+ resource.spec.replicas >= 3 &&
236+ has(resource.spec.securityContext) &&
237+ resource.spec.securityContext.runAsNonRoot == true
238+ ` ` `
239+
240+ # ## CEL Profile Format
241+
242+ Profiles that select rules using CEL checks must have `scanner_type : CEL`:
243+
244+ ` ` ` yaml
245+ documentation_complete: true
246+
247+ title: 'CIS VM Extension Benchmark'
248+
249+ description: |-
250+ Profile description.
251+
252+ scanner_type: CEL # REQUIRED: Marks this as a CEL profile (excluded from XCCDF)
253+
254+ selections:
255+ - kubevirt-nonroot-feature-gate-is-enabled
256+ - kubevirt-no-permitted-host-devices
257+ ` ` `
258+
259+ **Note:**
260+ - Profiles use `scanner_type : CEL` to indicate they target the CEL checking engine and should be excluded from XCCDF/datastream builds.
261+ - A rule can have both `cel/` (for CEL checks) and `template:` (for OVAL checks) to support both checking engines during migration.
262+
263+ **Important:** Use hyphens rule IDs (Kubernetes naming convention), not underscores.
264+
265+ # ## Enabling CEL Content for a Product
266+
267+ In `products/${PRODUCT}/CMakeLists.txt` :
268+
269+ ` ` ` cmake
270+ set(PRODUCT "ocp4")
271+ set(PRODUCT_CEL_ENABLED TRUE) # Enable CEL content generation
272+ ssg_build_product(${PRODUCT})
273+ ` ` `
274+
275+ See `docs/manual/developer/13_cel_content.md` for complete CEL documentation.
276+
161277# # Common Jinja2 Macros
162278
163279Used in rule descriptions, OCIL, fixtext, and warnings fields :
@@ -279,19 +395,35 @@ Common selection patterns:
279395# # Build Instructions
280396
281397` ` ` bash
282- # Build a single product (full build)
398+ # Build a single product (full build, includes CEL content if PRODUCT_CEL_ENABLED )
283399./build_product ocp4
284400
285- # Build data stream only (faster, skips guides and tables)
401+ # Build data stream only (faster, skips guides, tables, and CEL content)
402+ ./build_product ocp4 --datastream
403+ # Short form (only builds datastream):
404+ ./build_product ocp4 -d
405+ # Legacy form (still supported):
286406./build_product ocp4 --datastream-only
287407
408+ # Build data stream and CEL content
409+ ./build_product ocp4 --datastream --cel-content=ocp4
410+
411+ # Build only CEL content (no data stream)
412+ ./build_product --cel-content=ocp4
413+
414+ # Build CEL content for multiple products
415+ ./build_product --cel-content=ocp4,rhel9
416+
288417# Build with only specific rules (fastest, for testing individual rules)
289- ./build_product ocp4 --datastream-only --rule-id api_server_tls_security_profile
418+ ./build_product ocp4 --datastream --rule-id api_server_tls_security_profile
290419` ` `
291420
292421Build output goes to `build/`. The data stream file is at :
293422` build/ssg-<product>-ds.xml`
294423
424+ For products with CEL content enabled, the CEL content file is at :
425+ ` build/<product>-cel-content.yaml`
426+
295427# # Guidelines for Claude
296428
2974291. **Always show proposals before making changes.** Present the full content of any new or modified file and wait for explicit approval.
0 commit comments