Skip to content

Conversation

janisz
Copy link
Collaborator

@janisz janisz commented Aug 27, 2025

Add CEL Template for Custom Expression-Based Checks

This PR introduces a new cel-expression template that enables users to write custom checks using the Common Expression Language (CEL). This powerful addition allows for flexible, expression-based validation of Kubernetes resources without requiring Go code changes.

🚀 Features

  • CEL Expression Template: New cel-expression template in pkg/templates/cel/template.go:18
  • Flexible Resource Validation: Supports any Kubernetes resource type through objectkinds.Any
  • Expression-Based Logic: Write custom validation logic using CEL syntax
  • Access to Full Context: CEL expressions have access to both the subject resource and all other objects in the cluster

🔧 How It Works

The template provides two variables to CEL expressions:

  • subject: The current Kubernetes resource being evaluated
  • objects: Array of all Kubernetes resources in the current context

CEL expressions should return:

  • An empty string "" if the check passes
  • A descriptive string message if the check fails

📝 Usage Examples

Replace complex template logic with simple CEL expressions:

Example 1: Forbidden Annotation Check

customChecks:
  - name: "cel-forbidden-annotation"
    description: "Detect forbidden reloader annotation"
    template: "cel-expression"
    scope:
      objectKinds:
        - DeploymentLike
    params:
      check: |
        has(subject.metadata.annotations) && 
        subject.metadata.annotations["reloader.stakater.com/auto"] == "true" ? 
        "Object has reloader annotation" : ""

Example 2: IRSA Role Validation

customChecks:
  - name: "invalid-irsa-role"
    description: "Validate EKS IRSA role ARN format"
    template: "cel-expression"
    scope:
      objectKinds:
        - ServiceAccount
    params:
      check: |
        subject.metadata.annotations["eks.amazonaws.com/role-arn"].matches("^arn:aws:iam::\\d{12}:role/[\\w+=,.@-]{1,64}$") ? 
        "" : "Invalid EKS IAM role ARN format"

🧪 Testing

  • E2E Tests: New test case in e2etests/bats-tests.sh demonstrates the CEL template replacing traditional forbidden annotation checks
  • Unit Tests: Comprehensive test coverage in pkg/templates/cel/template_test.go
  • Test Data: Real-world examples in e2etests/testdata/cel-config.yaml and tests/checks/cel.yml

💡 Benefits

  1. No Code Changes Required: Add custom checks through configuration
  2. Powerful Expression Language: Leverage CEL's rich syntax for complex validations
  3. Cluster-Wide Context: Access to all resources enables cross-resource validation
  4. Type Safety: CEL provides compile-time expression validation
  5. Performance: Efficient evaluation of expressions

🔄 Migration Path

This template can replace many existing specialized templates. For example, the forbidden annotation functionality previously requiring a dedicated template can now be implemented with a simple CEL expression (as shown in the e2e tests).

📚 Resources


🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

@janisz janisz requested a review from rhybrillou as a code owner August 27, 2025 17:26
@janisz janisz requested a review from rukletsov August 27, 2025 17:26
Copy link
Member

@rukletsov rukletsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there is some AI-generated code in this PR. That's fine but I'd advice to add a note in the description about that .

Copy link
Member

@rukletsov rukletsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and compact, I'm a fan!

I understand that due to being an expression language, a CEL check is a bit limited compared to a check in some procedural language, where you can accumulate state. I'm not sure how important this limitation will be so I'm in favor of merging CEL support.

We can then try to implement open requests for checks using this CEL template and see how far we can go.

janisz added 6 commits August 28, 2025 18:49
Signed-off-by: Tomasz Janiszewski <[email protected]>
Signed-off-by: Tomasz Janiszewski <[email protected]>
Signed-off-by: Tomasz Janiszewski <[email protected]>
Signed-off-by: Tomasz Janiszewski <[email protected]>
Signed-off-by: Tomasz Janiszewski <[email protected]>
Signed-off-by: Tomasz Janiszewski <[email protected]>
@janisz
Copy link
Collaborator Author

janisz commented Aug 28, 2025

This dangling service can accumulate state, which means it can basically do anything we've done with Go. The issue is that it can get messy for big projects, especially since we're keeping it all in one YAML file.

Moving forward, we should make CEL development easier by:

  • Letting developers load the check body from a separate file.
  • Adding more extension functions to keep checks small.
  • Providing a way to merge multiple configuration files so we don't have to keep all the checks in a single YAML.

@janisz janisz requested a review from rukletsov August 28, 2025 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants