← Back to blog
Article

Entitlements vs Feature Flags — and why your SaaS needs both

They look similar. They both gate what users can do. But confusing the two is the single most common reason B2B SaaS teams end up with `if (plan === 'enterprise')` scattered across their codebase.

April 22, 202610 min read • Alexandre Bergère

Entitlements vs Feature Flags — and why your SaaS needs both (light theme)Entitlements vs Feature Flags — and why your SaaS needs both (dark theme)

Entitlements vs Feature Flags — and why your SaaS needs both

Entitlements and feature flags represented as two coordinated gates (light theme). Entitlements and feature flags represented as two coordinated gates (dark theme).

You ship a new feature behind a flag. A PM asks you to restrict it to Pro users. So you add a targeting rule: plan == "pro". It works. You move on.

Three months later, the pricing changes. The feature moves from Pro to a new Growth plan. Someone updates Stripe. Someone else updates the flag. But not at the same time. For two days, free users see a Pro feature. Nobody notices until a customer emails support asking why they lost access to something they never paid for.

This isn't a hypothetical. It happens every week in SaaS teams that treat feature flags as the place to encode business logic. And the root cause is always the same: two tools were available — feature flags and entitlements — and only one of them was used.

The good news: once you understand which tool answers which question, the problem disappears. This article draws a clear line between the two, explains why confusing them is expensive, and shows how they work together.


The 30-second definition

A feature flag answers a technical question: should this code path execute for this user, right now, in this environment?

Flags are about the state of the code. They're owned by engineers and product managers. They're typically short-lived — they exist to gate a rollout, enable a beta, or stand by as a kill-switch. Most flags should disappear within a few weeks of going to 100%.

An entitlement answers a commercial question: does this customer have the contractual right to use this capability, and up to what limit?

Entitlements are about the state of the contract. They're owned by product and revenue teams. They're long-lived — they exist as long as the plan exists. A new enterprise tier might introduce dozens of new entitlements, and they'll live alongside the product for years.


The four dimensions that separate them

The confusion is understandable because both can be expressed as booleans and both gate behavior. But they differ on four critical dimensions:

DimensionFeature FlagEntitlement
Question answered"Should this code run?""Is the customer allowed to do this?"
OwnerEngineering, ProductProduct, Revenue, Customer Success
LifespanShort (rollout → cleanup)Long (tied to the commercial offer)
Source of truthThe deployed codeThe signed contract
Typical valuesBoolean, string variant, JSON configBoolean, numeric quota, JSON config
Changes triggered byDeploys, experiments, rolloutsPlan upgrades, contracts, usage

Notice the last row. Flags change when your engineering team ships. Entitlements change when your revenue team closes a deal. Those two rhythms are completely different — and that's why trying to run both through the same tool usually fails.


When to use which: three concrete scenarios

Scenario 1 — Shipping a new AI assistant

You're building a new AI Assistant feature. You want to roll it out to 10% of users first, validate it works, then ramp to 100%.

This is a feature flag problem. Create a flag ai-assistant-enabled, put it behind a percentage rollout targeting rule, and monitor error rates. Once you're at 100% and confident, either remove the flag or keep it as a kill-switch.

const showAIAssistant = await client.getBooleanValue(
  'ai-assistant-enabled',
  false,
  { instanceId: 'inst_acme' }
);

There's no commercial dimension here yet. It's purely about code readiness.

Scenario 2 — Monetizing the AI assistant

Three months later, the feature is stable, everyone loves it, and Sales wants to charge for it. You decide AI Assistant is included in the Pro and Enterprise plans, with a monthly token quota: 100K tokens for Pro, 1M for Enterprise.

This is an entitlement problem — on two fronts.

First, a boolean entitlement ai-assistant: does this customer have access at all?

Second, a numeric entitlement ai-tokens-per-month: what's their monthly quota?

// Before letting the user call the AI
const hasAccess = await client.checkEntitlement('ai-assistant');
if (!hasAccess.granted) {
  return showUpgradePrompt();
}
 
// When processing the request
const usage = await client.meterUsage('ai-tokens-per-month', {
  model: 'gpt-4o',
  tokens_in: 1200,
  tokens_out: 450
});
if (!usage.within_limit) {
  return showQuotaExceeded(usage.limit, usage.current);
}

The code is identical across Starter, Pro, and Enterprise customers. The contract decides what happens, not the code.

Scenario 3 — The hybrid case: early access for select customers

Now Sales negotiates a custom deal. Acme wants early access to a new "Voice Interface" feature that's still in beta.

You need both tools.

  • The feature flag voice-interface-enabled gates the code. It's still in technical beta — you want to be able to roll it back instantly if something breaks.
  • An entitlement on Acme's license grants them the right. Or — if you're using Kaiten — a FLAG_GRANT voucher that temporarily overrides the flag for that specific customer's instance.

This is the scenario where most flag-only or entitlement-only tools break down. You need the two systems to talk to each other.

Timeline view of three rollout scenarios: flag-only, entitlement-only, and hybrid (light theme). Timeline view of three rollout scenarios: flag-only, entitlement-only, and hybrid (dark theme).

Why most B2B SaaS end up with if (plan === 'enterprise') everywhere

Three reasons. All three are fixable.

Reason 1 — The tools are usually separate. Your flag tool (LaunchDarkly, Unleash, Flagsmith) doesn't know what the customer paid for. Your billing tool (Stripe, Lago) doesn't know which features are live in prod. So engineers take the shortest path: hardcode the plan check. It works for three customers. It collapses at thirty.

Reason 2 — Engineering and Revenue teams don't share a data model. Engineering thinks in terms of flags, variants, rollout rules. Revenue thinks in terms of plans, line items, quotas. Without a shared abstraction, every new commercial package becomes a refactor.

Reason 3 — There's no open standard for entitlements. Feature flags have OpenFeature and OFREP (the OpenFeature Remote Evaluation Protocol) as industry-backed standards. Entitlements have… nothing. Each vendor invents their own SDK, their own API shape, their own lock-in story.


How Kaiten thinks about it

Kaiten was built on a single premise: flags and entitlements belong in the same control plane, because they describe two sides of the same coin — what's running, and what the customer paid for.

Kaiten unified control plane schema showing business systems, control plane engines, and customer instance integrations (light theme). Kaiten unified control plane schema showing business systems, control plane engines, and customer instance integrations (dark theme).

Concretely:

Feature flags in Kaiten are OpenFeature-native and OFREP-compatible. You use the standard OpenFeature SDKs — Go, TypeScript, Python, Java, Ruby, and more — and Kaiten's engine exposes the OFREP /ofrep/v1/evaluate/flags/{key} endpoint out of the box. No proprietary SDK. No lock-in. If you decide to move off Kaiten tomorrow, your flag code doesn't change — just the backend behind OFREP. CEL (Common Expression Language) is used for targeting rules, so your conditions are portable too.

Entitlements in Kaiten are first-class citizens, not bolted onto the flag engine. Three types — Boolean, Numeric (with metering), JSON Config — and they live in the License that represents a customer's plan. When Sales closes a deal, they assign the License. The entitlements follow automatically. When a customer upgrades, a single License change cascades to every Instance the customer has deployed. Zero PRs. Zero deploys. Zero if (plan === 'enterprise').

They share one audit trail. Every flag evaluation and every entitlement check writes to the same audit trail. Compliance gets one source of truth. Product gets adoption metrics across both. Sales gets consumption data. All without a single line of instrumentation code.

And they can reference each other. A voucher can grant a feature flag (FLAG_GRANT voucher type — unique to Kaiten). A feature flag can read from an entitlement as part of its targeting rule. The two systems are aware of each other because they live in the same model.

Here's what that looks like in practice. You define a feature as an entitlement on your Pro plan:

plan:
  key: pro
  entitlements:
    - feature: advanced-analytics
      value: true
    - feature: api-calls-per-month
      value: 10000
      type: NUMBER
      reset_period: MONTHLY

Then you progressively roll out a new version of the UI with a flag that references the entitlement:

flag:
  key: advanced-analytics-v2-ui
  targeting:
    - constraint: entitlement("advanced-analytics") == true
      rollout:
        percentage: 25

The flag only evaluates for users who have the entitlement. A free user will never see it, regardless of the rollout percentage. A Pro user has a 25% chance of seeing the new UI. If that Pro user downgrades to Free, their entitlement is revoked by the billing event, and the flag stops matching — automatically. No manual sync. No stale targeting rules.


A practical decision tree

Next time you're about to add a gate to your code, ask yourself three questions:

Decision tree to choose between feature flags, entitlements, or both (light theme). Decision tree to choose between feature flags, entitlements, or both (dark theme).
  1. Will this still exist in six months? No → feature flag (probably a short-lived one). Yes → likely an entitlement.

  2. Does the answer depend on what the customer paid? Yes → entitlement. No → feature flag.

  3. Who decides when it turns on? Engineering / Product → feature flag. Sales / Customer Success / the customer themselves → entitlement.

If the answer puts you on the fence, it's probably the hybrid case — and that's exactly why you need both tools in the same control plane.


The short version

  • Feature flags = is this code ready to run?
  • Entitlements = is this customer allowed to run it, and up to what limit?
  • You need both.
  • They work better together than apart.
  • Use open standards (OpenFeature, OFREP) for flags. Demand the same for entitlements.

Kaiten is the open-source control plane that unifies both, with OpenFeature-native flags, first-class entitlements, and one audit trail across the two. The contract enforces itself — not the other way around.

Explore the docs → · Read the open-source manifesto →

Unify flags and entitlements in one control plane

Kaiten connects OpenFeature-native flags, first-class entitlements, and metering in one model.