Kaiten

Core Concepts

Feature Flags

OpenFeature-compatible flags evaluated per instance over OFREP, with CEL targeting rules that can read the instance's contract directly.

A feature flag is a runtime decision: which variant of a value an instance receives right now. Kaiten's flags follow the OpenFeature standard — any OpenFeature SDK evaluates them, no proprietary client required — and their targeting rules are written in CEL. The distinctive part is what a rule can see: the instance's License, its entitlements, its customer, its zone. A flag can follow the contract without anyone listing customers.

Anatomy

A flag has a kebab-case slug (delivery-tracking-enabled), a value type (boolean, string, number, object), a set of named variants (on → true, off → false; an object flag like promo-banner carries payloads), a default variant, an enabled switch, and an ordered list of targeting rules. Each rule is a name, a CEL expression, and what it serves when the expression is true: a fixed variant, a weighted split across variants for a percentage rollout (random-discount is a 50/50 experiment), or a share that grows between two dates. Splits bucket each subject deterministically per flag, so one rollout's cohort never leaks into another's.

Evaluation

Evaluation happens over OFREP — POST /ofrep/v1/evaluate/flags/{key} for one flag, POST /ofrep/v1/evaluate/flags for all of them, GET /openfeature/v0/manifest for the flag manifest — with a context that names the customer as targetingKey and the instance under kaiten.instanceSlug: {"context": {"targetingKey": "sakura-tokyo", "kaiten": {"instanceSlug": "sakura-tokyo-prod"}}}. Every flag goes through the same steps:

  1. Kill switch. enabled: false serves the default variant with reason DISABLED. No rule is evaluated — not even one that would match everyone.
  2. Context. A context that fails validation — no targetingKey — is refused with 400 and the error code PROVIDER_FATAL; no variant is served.
  3. Facts. The __kaiten facts are computed and placed in the context — the License and entitlements of the customer the targetingKey names, read from its oldest instance, and the instance, customer, and zone that kaiten.instanceSlug names; anything the caller sent under __kaiten is discarded.
  4. Rules, in order. A rule that cannot run is skipped and recorded. A rule that is false is skipped. The first rule that is true serves its variant — reason TARGETING_MATCH for a fixed variant, SPLIT for a percentage or date rollout.
  5. No match. The default variant, reason DEFAULT — or, when the flag has no rules at all, the default variant's own reason, STATIC for a fixed one.

The response carries the value, the variant, and the reason. A rule that cannot run is skipped and never read as a no: a typo in one expression does not silently turn a feature off for everyone. The value falls through to the next rule or the default, and the failure is attached to the response metadata under kaiten.brokenTargetingRules, where the rule's author sees it — and can catch it earlier with the lint and rehearsal operations.

Rules read the contract

Before a rule runs, Kaiten places server-computed facts under the reserved __kaiten name — nothing the caller sends can override them:

  • __kaiten.license.slug (the version), __kaiten.license.familySlug (the product), __kaiten.license.type
  • __kaiten.entitlements["<slug>"], in the shape of the entitlement's type: monthly-orders, a NUMBER, with limit, used, remaining, percentage, unlimited; delivery-tracking, a BOOLEAN, as the boolean the License grants; support-tier, a CONFIG, as the object it grants
  • __kaiten.instance (slug, status, lifecycle stage, typed metadata), __kaiten.customer, __kaiten.deploymentZone
__kaiten.entitlements['delivery-tracking'] == true

That single rule is all delivery-tracking-enabled has: it reads the delivery-tracking grant as the boolean the License grants, so the flag resolves to on for Sakura Tokyo and Kappa Kyoto, whose versions of Premium grant it, and off for Ninja Osaka on Starter and for Demo Restaurant, whose version of Standard does not. Upgrade Ninja Osaka's License and the flag follows — no flag edit, no deploy.

The License itself is a fact too: promo-banner serves its salmon-week payload where __kaiten.license.familySlug in ['standard', 'premium'] — the family slug, so the rule keeps matching when a new version is published. Everything else in the context is yours to send — analytics-dashboard-enabled combines __kaiten.customer.slug == 'sakura-tokyo' with a caller-supplied orderCount > 10.

The Entitlement is the commercial right; the flag is the runtime decision that may read it. Keeping them distinct is what lets the same flag also carry a percentage rollout or a kill switch — see Entitlement, not Feature.

Every evaluation is recorded

Each evaluation emits FEATURE_FLAG_EVALUATED — the flag, the variant, the reason — deliberately without the evaluation context, so no targeting key or user attribute enters the audit trail. An evaluation is addressed by a targeting key, and its entry is recorded for the organization, without an Instance: it is read in the organization's trail, never in an Instance's — Answer who had access shows how. Flag changes are events too (FEATURE_FLAG_CREATED, FEATURE_FLAG_UPDATED, FEATURE_FLAG_DELETED).

Where to go next

In depth, in the Feature Flags deep-dive: variants, targeting rules, and OpenFeature SDK setup. The quickstart creates a flag whose rule reads a quota and watches the contract turn it off.

Exact reference: data model.

On this page