Target flags with CEL

Common Expression Language (CEL) provides the logic for sophisticated, rule-based flag evaluations. It lets you create precise targeting rules by combining multiple user or request attributes using logical operators.

This guide shows you how to define flags with CEL rules and update evaluation specs.

Prerequisites

Before you begin, ensure you have:

  1. Completed the Deploy feature flags quickstart.
  2. A gcloud environment configured to manage App Lifecycle Manager resources.

Logical operators and syntax

CEL supports standard logical operators to build complex conditions:

  • && logical AND
  • || logical OR
  • ! logical NOT
  • in check if a value exists in a list

Define attributes

CEL attributes are specific data points, such as source.ip, request headers, or paths, used within boolean expressions to define security or routing policies.

Any attribute used in a CEL condition must be explicitly defined and listed in the attributes array of the EvaluationSpec. If an attribute is used in a condition but missing from the list, the API will reject the request.

Create an attribute

You can use App Lifecycle Manager to create CEL attributes.

To create a plan attribute, run the command:

gcloud beta app-lifecycle-manager flags attributes create "plan-attr" \
    --key="plan" \
    --attribute-value-type="STRING" \
    --location=global

To create a country attribute, run the command:

gcloud beta app-lifecycle-manager flags attributes create "country-attr" \
    --key="country" \
    --attribute-value-type="STRING" \
    --location=global

To create a platform attribute, run the command:

gcloud beta app-lifecycle-manager flags attributes create "platform-attr" \
    --key="platform" \
    --attribute-value-type="STRING" \
    --location=global

Configure a flag with CEL rules

When creating or updating a flag, define the evaluation logic in the evaluation-spec.

For example, this snippet enables a feature for premium customers in Germany using their mobile app.

gcloud beta app-lifecycle-manager flags create "advanced-reporting-flag" \
    --key="advanced-reporting-flag" \
    --flag-value-type=BOOL \
    --unit-kind="UNIT_KIND_NAME" \
    --location=global \
    --evaluation-spec='{
      "rules": [{
        "id": "premium_mobile_users_in_germany",
        "condition": "plan == \"premium\" && country == \"DE\" && platform == \"mobile\"",
        "target": "enabled"
      }],
      "defaultTarget": "disabled",
      "attributes": [
        "projects/PROJECT_ID/locations/global/flagAttributes/plan-attr",
        "projects/PROJECT_ID/locations/global/flagAttributes/country-attr",
        "projects/PROJECT_ID/locations/global/flagAttributes/platform-attr"
      ]
    }'

Replace PROJECT_ID, and UNIT_KIND_NAME with your values.

Application integration

Your application must inject the attributes into the evaluation context at runtime.

Python example:

from openfeature.evaluation_context import EvaluationContext

eval_ctx = EvaluationContext(
    targeting_key=user_id,
    attributes={
        "plan": "premium",
        "country": "DE",
        "platform": "mobile"
    }
)

is_enabled = client.get_boolean_value("advanced-reporting-flag", False, eval_ctx)

Best practices

  • Order of Evaluation: Rules are evaluated sequentially. The first rule that evaluates to true determines the flag's value.
  • Safe Defaults: If a user context is missing a required attribute for a condition, the evaluation engine will skip that specific rule.
  • Character Limits: CEL expressions can be up to 4,096 bytes (4kB) in size.

What's next