FEATUREFLOW V2AI-native · MCP-enabled ·30% off your first year:NEXT30claim →
Continuous DeliveryOct 23, 2026

What to put in the user you pass to a feature flag

O
Oliver Oldfield-Hodge
Featureflow

Which fields do you pass when you ask whether a flag is on? Most teams answer by handing over the whole user record.

It works on day one. Then a rule needs the plan, so the plan goes in. Then someone wants a beta for one company, so the company goes in. A year later the context holds an email address, a full name and a phone number, and nobody can say which of them any rule reads.

That context travels. You build it in the request handler, but the same user shows up in evaluation events, in the listener you wired to your analytics tool, and in anything you log next to the result. A field you added for convenience is now in each of those places.

Keep it small

Targeting needs an id and the attributes a rule compares against. The id has two jobs: percentage rollouts hash it, so the same id always gets the same variant, and it identifies the user in evaluation events. Use an internal id that means nothing outside your system, not an email.

  • Opaque id. A database key or UUID. It stays the same when someone changes their email, so their variant does not change with it.
  • Coarse attributes. plan, country, roles. Pass what a rule actually uses, not every column you have.
  • Account id for company-wide betas. Target companyId instead of listing every person at the company.
import Featureflow from 'featureflow-node-sdk';

// One place builds the context, so nobody adds fields ad hoc.
export function flagUser(u: AppUser) {
  return new Featureflow.UserBuilder(u.id)
    .withAttribute('plan', u.plan)
    .withAttribute('country', u.country)
    .withAttribute('companyId', u.companyId)
    .withAttributes('roles', u.roles)
    .build();
}

if (featureflow.evaluate('new-reports', flagUser(user)).isOn()) {
  // ...
}

Rules are evaluated inside your process, so the context does not have to leave your servers for a flag to resolve. That is a reason to be strict about it, because the wider copies come from your own code: the evaluation listener, the log line, the error report.

One builder, one review rule

The function above matters more than the list. When every evaluation builds its user in the same place, adding an attribute is a visible change to a single file, and a reviewer can ask which rule needs it. When each call site assembles its own user, the fields drift and nobody sees it.

If you need to target by something sensitive, such as an email domain for an internal beta, pass the derived value (isStaff: true) and keep the address itself out. Your rule gets the same answer with less data attached.

In Featureflow, the attributes you pass are the ones your targeting rules can use. The docs cover defining a user and targeting by custom attributes.

Today, search your code for the places that build a flag user. Collapse them into one function and delete every field no rule reads.

#FeatureFlags#Privacy#Targeting#ContinuousDelivery#DevOps

Target on the fields that matter

Start free with Featureflow. Target by plan, company or role, and keep an audit trail of every change.

Start Now (Free)

Related Articles