Skip to content

Commit ba8e930

Browse files
committed
Improve docs and style guides with CEL rules info
1 parent 12fde16 commit ba8e930

3 files changed

Lines changed: 171 additions & 10 deletions

File tree

docs/manual/developer/03_creating_content.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ build files/configuration, etc.
2626
</tr>
2727
<tr class="odd">
2828
<td><p><code>applications</code></p></td>
29-
<td><p>Contains security content for applications such as OpenShift or OpenStack. Contains rules, OVAL checks, Ansible tasks, Bash remediations, etc.</p></td>
29+
<td><p>Contains security content for applications such as OpenShift or OpenStack. Contains rules, OVAL checks, CEL checks, Ansible tasks, Bash remediations, etc. For Kubernetes/OpenShift CEL rules, see <a href="12_cel_content.md">CEL Content</a>.</p></td>
3030
</tr>
3131
<tr class="even">
3232
<td><p><code>shared</code></p></td>

docs/manual/developer/04_style_guide.md

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,90 @@ Rules sections must be in the following order, if they are present.
274274
* Must be a valid rule id
275275
* `template`
276276

277+
#### CEL Rule Sections
278+
279+
CEL (Common Expression Language) rules are used for Kubernetes/OpenShift compliance checks.
280+
CEL rules use different fields than traditional OVAL-based rules.
281+
282+
CEL rule sections must be in the following order, if present:
283+
284+
* `documentation_complete`
285+
* `title`
286+
* `description` (HTML Like)
287+
* `rationale` (HTML Like)
288+
* `severity`
289+
* `identifiers` (Optional)
290+
* Keys must be in alphabetical order
291+
* `references` (Optional)
292+
* Keys must be in alphabetical order
293+
* `ocil_clause` (Optional)
294+
* `ocil` (HTML Like, Optional)
295+
* `failure_reason` (Optional)
296+
* Must be a block
297+
* Must describe the condition when the check fails
298+
* `check_type`
299+
* Must be `Platform` for Kubernetes/OpenShift checks
300+
* `scanner_type`
301+
* Must be `CEL` for CEL rules
302+
* `inputs`
303+
* Must be a list of at least one input
304+
* Each input must have:
305+
* `name` - Variable name used in the CEL expression
306+
* `kubernetes_input_spec` - Kubernetes resource specification
307+
* `api_version` - Kubernetes API version (e.g., `v1`, `apps/v1`)
308+
* `resource` - Resource type in plural form (e.g., `pods`, `deployments`)
309+
* `resource_name` (Optional) - Specific resource name to query
310+
* `resource_namespace` (Optional) - Specific namespace to query
311+
* `expression`
312+
* Must be a valid CEL expression that evaluates to boolean
313+
* Must use variables defined in `inputs`
314+
* Should use `has()` to check for field existence before accessing
315+
* Should be formatted for readability using multi-line block syntax for complex expressions
316+
317+
CEL rules must NOT include:
318+
* `template` field (CEL rules don't use templates)
319+
* `platform` field (implied by `scanner_type: CEL`)
320+
321+
Example CEL rule structure:
322+
323+
```yaml
324+
documentation_complete: true
325+
326+
title: 'Rule Title in Title Case'
327+
328+
description: |-
329+
Description of what the rule checks.
330+
331+
rationale: |-
332+
Why this rule matters for security/compliance.
333+
334+
severity: medium
335+
336+
scanner_type: CEL
337+
338+
check_type: Platform
339+
340+
expression: |-
341+
resource.spec.enabled == true &&
342+
has(resource.spec.field) &&
343+
resource.spec.field == "expected_value"
344+
345+
inputs:
346+
- name: resource
347+
kubernetes_input_spec:
348+
api_version: v1
349+
resource: configmaps
350+
resource_name: my-config
351+
resource_namespace: default
352+
353+
ocil: |-
354+
Run the following command:
355+
<pre>$ oc get configmap my-config -n default</pre>
356+
357+
failure_reason: |-
358+
The resource is not properly configured.
359+
```
360+
277361
### Group
278362
279363
This section describes the style guide around the `group.yml` files.
@@ -354,21 +438,27 @@ Control sections must be in the following order, if they are present.
354438

355439
#### Profile Sections
356440

357-
Control sections must be in the following order, all sections are required unless otherwise noted.
441+
Profile sections must be in the following order, all sections are required unless otherwise noted.
358442

359443
* `documentation_complete`
360-
* `id`
361-
* `metadata`
444+
* `metadata` (Optional)
362445
* `reference`
363446
* `version`
364447
* `SMEs`
365448
* `title`
366449
* Shall be short and descriptive
367450
* `description` (HTML-Like)
451+
* `platform` (Optional)
452+
* Must be a valid platform identifier (e.g., `ocp4`, `rhel9`)
453+
* `scanner_type` (Optional)
454+
* Must be `CEL` for CEL profiles
455+
* CEL profiles can only select CEL rules
456+
* CEL profiles are excluded from XCCDF/OVAL generation
368457
* `extends` (Optional)
369458
* Must be valid id of another profile id
370459
* `selections`
371460
* Must be valid rule ids
461+
* For CEL profiles, must only contain CEL rule ids (using hyphens, not underscores)
372462

373463
## Remediation
374464

docs/manual/developer/06_contributing_with_content.md

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -668,12 +668,19 @@ Tips:
668668
669669
### Checks
670670
671-
Checks are used to evaluate a Rule. There are two types of check content
672-
supported by ComplianceAsCode: OVAL and SCE. Note that OVAL is standardized
673-
by NIST and has better cross-scanner support than SCE does. However, because
674-
SCE can use any language on the target system (Bash, Python, ...) it is much
675-
more flexible and general-purpose than OVAL. This project generally encourages
676-
OVAL unless it lacks support for certain features.
671+
Checks are used to evaluate a Rule. There are three types of check content
672+
supported by ComplianceAsCode: OVAL, CEL, and SCE.
673+
674+
* **OVAL** (Open Vulnerability and Assessment Language) - Standardized by NIST with better cross-scanner support. Used for traditional operating system compliance checks (file system, processes, packages). Generally the preferred choice for OS-level checks.
675+
676+
* **CEL** (Common Expression Language) - Used for Kubernetes and OpenShift platform compliance checks. CEL rules evaluate Kubernetes API resources without requiring shell access to nodes. See [CEL Content](12_cel_content.md) for complete documentation on creating CEL rules.
677+
678+
* **SCE** (Script Check Engine) - Can use any language on the target system (Bash, Python, ...) making it more flexible and general-purpose than OVAL, but with less cross-scanner support.
679+
680+
This project generally encourages using:
681+
- OVAL for Linux/OS checks
682+
- CEL for Kubernetes/OpenShift platform checks
683+
- SCE only when OVAL lacks support for certain features
677684
678685
#### OVAL Check Content
679686
@@ -946,6 +953,70 @@ means:
946953
</tbody>
947954
</table>
948955
956+
### CEL Check Content
957+
958+
[CEL](https://github.com/google/cel-spec) (Common Expression Language) is a mechanism
959+
for evaluating Kubernetes and OpenShift API resources for compliance checking. CEL checks
960+
are used by the [compliance-operator](https://github.com/ComplianceAsCode/compliance-operator)
961+
to perform platform-level compliance checks without requiring shell access to nodes.
962+
963+
CEL rules are defined directly in the `rule.yml` file using specialized fields:
964+
965+
* `scanner_type: CEL` - Marks the rule as a CEL rule
966+
* `check_type: Platform` - Indicates this is a platform-level check
967+
* `expression` - The CEL expression that evaluates to boolean (true=pass, false=fail)
968+
* `inputs` - List of Kubernetes resources to evaluate
969+
* `failure_reason` - Optional custom failure message
970+
971+
Within a rule's `inputs` section, each input specifies a Kubernetes resource using `kubernetes_input_spec`:
972+
973+
* `api_version` - Kubernetes API version (e.g., `v1`, `apps/v1`)
974+
* `resource` - Resource type in plural form (e.g., `pods`, `deployments`)
975+
* `resource_name` - Optional: specific resource name to query
976+
* `resource_namespace` - Optional: specific namespace to query
977+
978+
**Important notes:**
979+
980+
* CEL rules are **excluded** from XCCDF/OVAL DataStreams
981+
* CEL rules generate a separate `${PRODUCT}-cel-content.yaml` file
982+
* CEL profiles can only select CEL rules
983+
* Rule directory names should use hyphens (Kubernetes naming convention)
984+
985+
For complete documentation on creating CEL rules, see [CEL Content](12_cel_content.md).
986+
987+
Example CEL rule:
988+
989+
```yaml
990+
scanner_type: CEL
991+
check_type: Platform
992+
993+
expression: |-
994+
resource.spec.replicas >= 3 &&
995+
has(resource.spec.template.spec.securityContext) &&
996+
resource.spec.template.spec.securityContext.runAsNonRoot == true
997+
998+
inputs:
999+
- name: resource
1000+
kubernetes_input_spec:
1001+
api_version: apps/v1
1002+
resource: deployments
1003+
resource_name: my-app
1004+
resource_namespace: default
1005+
```
1006+
1007+
To build CEL content for a product, enable it in the product's `CMakeLists.txt`:
1008+
1009+
```cmake
1010+
set(PRODUCT "ocp4")
1011+
set(PRODUCT_CEL_ENABLED TRUE)
1012+
ssg_build_product(${PRODUCT})
1013+
```
1014+
1015+
## Remediations
1016+
1017+
The following sections describe remediation content. Note that CEL rules do **not** support
1018+
remediation content - they are check-only.
1019+
9491020
### Ansible
9501021
9511022
> **Important**

0 commit comments

Comments
 (0)