Skip to content

Commit e899db1

Browse files
author
hadar-co
authored
add page for CEL support (#213)
* add page for CEL support * add page for CEL support * add page for CEL support * add page for CEL support * add page for CEL support * add page for CEL support * add page for CEL support * add page for CEL support
1 parent f32de76 commit e899db1

File tree

5 files changed

+138
-7
lines changed

5 files changed

+138
-7
lines changed

Diff for: docs/custom-rules/cel-support/index.mdx

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: CEL support
3+
slug: /custom-rules/cel-support
4+
---
5+
6+
Datree supports writing custom rules in the [CEL](https://github.com/google/cel-spec) language, by utilizing a custom JSON Schema keyword.
7+
8+
:::info Supported version
9+
Writing custom rules in CEL is supported in CLI version [1.9.19](https://github.com/datreeio/datree/releases/tag/1.9.19) and above.
10+
:::
11+
12+
## Required properties
13+
14+
In addition to the basic [required format](/custom-rules/custom-rules-overview#rule-format), a CEL custom rule has the following requirements:
15+
16+
- The `schema` property **must** have a property named `CELDefinition`, which is an array of items.
17+
- Each item **must** have a property named `expression` that contains the logic of the rule written in CEL. Within the expression, use `object` to reference the resource being evaluated (see example below).
18+
- Each item **may** have a property named `message`, which specifies what print when the expression is violated.
19+
20+
:::tip Online CEL validation
21+
Ensure the validity of your CEL expressions by testing them against resources using an [online CEL playground](https://playcel.undistro.io/).
22+
:::
23+
24+
#### Example:
25+
26+
The following schema requires that resources of kind `ServiceAccount` have the `automountServiceAccountToken` property set to `false`:
27+
28+
```yaml
29+
schema:
30+
CELDefinition:
31+
- expression: "object.kind != 'ServiceAccount' || (has(object.automountServiceAccountToken) && object.automountServiceAccountToken == false)"
32+
message: "ServiceAccounts must have automountServiceAccountToken set to false" # `message` is optional
33+
```
34+
35+
---
36+
37+
### Constraints
38+
39+
In the above example, the constraint `object.kind != 'ServiceAccount'` is a part of the CEL logic.
40+
You can also write such a constraint in JSON schema and write the rest of the logic using CEL:
41+
42+
```yaml
43+
schema:
44+
# Constraint - enforce rule only on `ServiceAccount` resources
45+
if:
46+
properties:
47+
kind:
48+
enum:
49+
- ServiceAccount
50+
then:
51+
CELDefinition:
52+
- expression: "has(object.automountServiceAccountToken) && object.automountServiceAccountToken == false"
53+
```
54+
55+
#### For more examples, including a complete custom rules YAML, see the [examples page](/custom-rules/examples).

Diff for: docs/custom-rules/custom-rules-overview/index.mdx

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ slug: /custom-rules/custom-rules-overview
66
In addition to Datree's built-in rules, you can also write your own rules and add them to your policies.
77
The custom rule engine is based on [JSON Schema](https://json-schema.org/), so it supports both YAML and JSON declarative syntax.
88

9-
Custom rules can be written directly in **JSON Schema** or in [**Rego**](/custom-rules/rego-support).
9+
Custom rules can be written directly in **JSON Schema**, in [**Rego**](/custom-rules/rego-support), or in [CEL](/custom-rules/cel-support).
1010

1111
:::info Note
1212
Note that using custom rules is possible only when in [Policy as code](/dashboard/policy-as-code) mode.
@@ -34,7 +34,7 @@ Every custom rule must have the following properties:
3434
- **identifier** - a unique ID to associate with a policy.
3535
- **name** [OPTIONAL] - a title that will be shown in Datree's output when a rule fails.
3636
- **defaultMessageOnFailure** [OPTIONAL] - a message that is shown when the property `policies.name[].rules.messageOnFailure` is empty (unique to each identifier).
37-
- **schema** - a custom rule logic written in JSON Schema (as YAML) or in [Rego](/custom-rules/rego-support).
37+
- **schema** - a custom rule logic written in JSON Schema (as YAML), in [Rego](/custom-rules/rego-support), or in [CEL](/custom-rules/cel-support).
3838

3939
### Policies file format
4040

@@ -78,3 +78,4 @@ The provided examples are written in YAML schema, but custom rules can also be s
7878
- [Online YAML Schema validator](https://yamlschemavalidator.datree.io/)
7979
- [Online JSON Schema validator](https://www.jsonschemavalidator.net/)
8080
- [Online Rego validator](https://play.openpolicyagent.org/)
81+
- [Online CEL validator](https://playcel.undistro.io/)

Diff for: docs/custom-rules/examples/index.mdx

+79-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Examples
33
slug: /custom-rules/examples
44
---
55

6-
Here you will find examples for custom rules and common use-cases when writing policy enforcement logic, using both **JSON schema** and **Rego**.
6+
Here you will find examples for custom rules and common use-cases when writing policy enforcement logic, using **JSON schema**, **Rego**, and **CEL**.
77

88
To see an example of a ready-to-publish custom rules YAML, [skip ahead](/custom-rules/examples#full-custom-rule-examples).
99

@@ -147,6 +147,43 @@ regoDefinition:
147147
}
148148
```
149149

150+
---
151+
152+
## CEL
153+
154+
### Ensure resource name of a certain kind begins with a specific prefix
155+
156+
The following schema ensures all Deployments have a configured name that begins with `exmpl-`:
157+
158+
```yaml
159+
if:
160+
properties:
161+
kind:
162+
enum:
163+
- Deployment
164+
then:
165+
CELDefinition:
166+
- expression: "object.metadata.name.startsWith("exmpl-")"
167+
message: "Deployments must have a name that begins with `exmpl-`" # `message` is optional
168+
```
169+
170+
### Ensure a resource has a property with a specific value
171+
172+
The following schema ensures all containers in a Pod have a configured `securityContext.readOnlyRootFilesystem` set to `true`:
173+
174+
```yaml
175+
if:
176+
properties:
177+
kind:
178+
enum:
179+
- Pod
180+
then:
181+
CELDefinition:
182+
- expression: "object.spec.containers.all(container, has(container.securityContext) && has(container.securityContext.readOnlyRootFilesystem) && container.securityContext.readOnlyRootFilesystem == true)"
183+
message: "Containers must have a read-only root filesystem" # `message` is optional
184+
```
185+
186+
150187
---
151188
152189
## Full custom rule examples
@@ -255,3 +292,44 @@ customRules:
255292
labelIsMissing := helpers.check_if_missing(missing)
256293
}
257294
```
295+
296+
### CEL
297+
298+
This example has two custom rules written in CEL and added to the policy `Default`:
299+
300+
```yaml
301+
apiVersion: v1
302+
policies:
303+
- name: Default
304+
rules:
305+
- identifier: CUSTOM_DEPLOYMENT_NAME_PREFIX
306+
messageOnFailure: Deployments must have a name that begins with `exmpl-`
307+
- identifier: CUSTOM_CONTAINERS_READ_ONLY_ROOT_FILESYSTEM
308+
messageOnFailure: Containers must have a read-only root filesystem
309+
customRules:
310+
- identifier: CUSTOM_DEPLOYMENT_NAME_PREFIX
311+
name: Ensure Deployment has a valid name [CUSTOM RULE]
312+
defaultMessageOnFailure: Deployments must have a name that begins with `exmpl-`
313+
schema:
314+
if:
315+
properties:
316+
kind:
317+
enum:
318+
- Deployment
319+
then:
320+
CELDefinition:
321+
- expression: "object.metadata.name.startsWith("exmpl-")"
322+
message: "Deployments must have a name that begins with `exmpl-`"
323+
- identifier: CUSTOM_CONTAINERS_READ_ONLY_ROOT_FILESYSTEM
324+
name: Ensure Pod containers have a read-only root filesystem [CUSTOM RULE]
325+
defaultMessageOnFailure: Containers must have a read-only root filesystem
326+
schema:
327+
if:
328+
properties:
329+
kind:
330+
enum:
331+
- Pod
332+
then:
333+
CELDefinition:
334+
- expression: "object.spec.containers.all(container, has(container.securityContext) && has(container.securityContext.readOnlyRootFilesystem) && container.securityContext.readOnlyRootFilesystem == true)"
335+
```

Diff for: docs/custom-rules/rego-support/_category_.json

-4
This file was deleted.

Diff for: sidebars.js

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ const sidebars = {
185185
items: [
186186
"custom-rules/custom-rules-overview/index",
187187
"custom-rules/rego-support/index",
188+
"custom-rules/cel-support/index",
188189
"custom-rules/examples/index",
189190
"custom-rules/multiple-property-paths/index",
190191
"custom-rules/resource-quotas/index",

0 commit comments

Comments
 (0)