Skip to content

Upgrade to the Full Platform

You adopted Feature Flags standalone, and now you want Bridge auth (login, users, tenants) or Bridge billing (plans, checkout). Good news: nothing breaks, nothing is rewritten. Your flags, rules, and custom attributes keep working exactly as they are — the platform just starts contributing richer context that you previously had to supply yourself.

Bridge contributes auth-derived attributes to every flag evaluation automatically, namespaced as bridge: in the rule builder:

AttributeSource (JWT claim)
bridge:user.idsub
bridge:user.rolerole
bridge:user.emailemail
bridge:tenant.idtid
bridge:tenant.planplan
bridge:privilegesprivileges

If you were sending role, tenant_id, or similar as custom attributes, you can stop — and retarget your rules onto the bridge: keys, which are read from the verified token rather than whatever your code passed in.

Bridge auth in the Svelte SDK wires this up during bootstrap; there is no extra flag-side code.

Before (standalone — you supply role/plan yourself):

<script lang="ts">
import { useFlag } from '@nebulr-group/bridge-svelte/flags';
const enterprise = useFlag('enterprise_feature', false, () => ({
attributes: { role: currentUser.role, plan: currentTenant.plan },
}));
</script>

After (Bridge auth enabled — attributes flow from the session automatically):

<script lang="ts">
import { useFlag } from '@nebulr-group/bridge-svelte/flags';
const enterprise = useFlag('enterprise_feature', false);
</script>

In the admin, retarget the rule from custom:role to bridge:user.role.

Before (standalone — you pull role/tenant off your own auth middleware per call):

const enabled = this.flags.flag('enterprise_feature', false, {
identity: req.user.id,
attributes: { role: req.user.role, tenant_id: req.user.tenantId },
});

After (Bridge auth enabled — register the provider once at bootstrap; it reads the verified claims on every eval):

import { AuthAttributeProvider } from '@nebulr-group/bridge-auth-core';
// once, e.g. in your module's onModuleInit
this.flags.bridge.registerAttributeProvider(
new AuthAttributeProvider({ getClaims: () => getCurrentClaims() }),
);
// per call — identity only, attributes come from the provider
const enabled = this.flags.flag('enterprise_feature', false, {
identity: req.user.id,
});

Also worth adopting: BridgeContextInterceptor reads the x-bridge-context header your frontend SDK sends, so frontend and backend evaluate with the same identity — consistent buckets on both sides of the wire, no hand-rolled plumbing.

What changes when you enable Bridge billing

Section titled “What changes when you enable Bridge billing”

The billing subsystem contributes live subscription state on every eval:

AttributeType
bridge:billing.planstring (plan slug)
bridge:billing.trialboolean
bridge:billing.subscription.statusstring
bridge:billing.quota.<metric>.used / .limit / .remaining / .percent_usednumber
bridge:billing.entitlement.<name>boolean

Rules like “warn when usage approaches the cap” become pure admin configuration:

bridge:billing.quota.ai_completions.percent_used gt 80 → show_quota_warning = true

When a customer upgrades, Bridge pushes the change live — flags targeting bridge:billing.plan re-evaluate within a second, with no app code involved.

If your code supplies an attribute with the same key as a Bridge-managed one, your value wins. This is deliberate and documented behavior — the developer owns the context. Two consequences:

  1. Debuggability: the flag detail page in the admin surfaces the collision visibly, so an override is never a silent mystery.
  2. Security: never forward attributes like role or plan from the client to your backend evals (e.g. via the propagation header). The backend’s own providers read them from server-side sources of truth — honoring a client-sent role: admin would let users grant themselves features.
  1. Enable Bridge auth in your app (Auth guide) — registration, login, sessions.
  2. Confirm the attribute provider is active. Svelte: automatic at bootstrap. NestJS: register AuthAttributeProvider as shown above. Evaluate any flag, then check the rule builder’s attribute picker — the bridge:user.* keys should appear with observed values.
  3. Retarget rules in the admin from your custom: keys to the bridge: equivalents (custom:rolebridge:user.role). Use the live match count to confirm the new rule matches the same population before removing the old condition.
  4. Remove the redundant custom attributes from your flag calls (attributes: { role: … } and friends).
  5. Verify targeting end to end: log in as users with different roles/plans and confirm flag values, or watch the per-flag eval value distribution.

Repeat the same shape for billing: enable Bridge payments, watch bridge:billing.* appear in the picker, retarget, remove your own plan plumbing.

  • Custom attributes keep flowing forever — adopting auth/billing doesn’t change how custom: attributes work, and rules targeting them keep evaluating.
  • The upgrade is per-flag and incremental. Migrate one rule at a time; mixed targeting (some flags on custom:, some on bridge:) is fine indefinitely.
  • Rolling back (disabling a subsystem) simply stops the bridge: attributes from being contributed; rules that target them stop matching, and the admin warns about rules targeting attributes the SDK no longer sends.