On this page

Using Private Attributes

Use private attributes in Statsig SDKs to evaluate feature gates and experiments without sending sensitive user data to Statsig servers.

Evaluating feature gates, dynamic configs, segments, and experiments without logging user data

Statsig takes the privacy of user data seriously. If you have legal requirements that prevent sending PII to third parties, or prefer not to send PII to a third-party service, you can still use Statsig for feature gating, configs, or experiments.

How private attributes work

You can make any field used for evaluation private.

Making the userID field private breaks your experience in the Statsig console: the Users tab, metrics charts, event logs, and Pulse metrics won't populate accurately. To hide the user ID, use a stable, one-way hash to preserve the ability to analyze user behavior.

For example, let's say you want to use an email condition:

  1. Create a feature gate with a condition that passes on certain emails or domains
  2. Pass email: email@domain.com in privateAttributes rather than in the top level email field
  3. Test it out in the Test Gate console after saving changes

Private attributes

When evaluating rules and conditions, Statsig checks for fields at the top level, then in custom attributes, and finally in privateAttributes. Not passing email at the top level causes the evaluator to check custom and then privateAttributes before evaluating the condition.

To keep ip and userAgent private while still using browser or IP checks in the console, place them in the privateAttributes dictionary instead of at the top level of the user object. The same applies to country, locale, custom fields, and so on.

The statsig-node SDK illustrates how this works (this is also how gates are evaluated on Statsig servers): https://github.com/statsig-io/node-js-server-sdk/blob/d1cb9431fb68b40f840254fce70363de1dc51aa5/src/Evaluator.js#L374

Don't provide a privateAttribute key anywhere else in the user object. Statsig drops the entire privateAttributes dictionary, but any duplicate fields at the top level or in the custom object are still logged (and evaluated against).

Client vs server SDKs

Client and single-user environment SDKs send the user object with the initialize call to evaluate the user against every gate in your Statsig project. The SDK sends privateAttributes with this call, but Statsig servers don't store or log them. Statsig servers require the privateAttributes field to evaluate gate, config, and experiment conditions, then strip it from the user object before any logging occurs. Client SDKs remove privateAttributes before logging any events; the SDK uses the field only for gate evaluation.

Example with the @statsig/js-client SDK: https://github.com/statsig-io/js-client-monorepo/blob/17fb70f1bea00d07e156cf6ff03b8024bbc1b197/packages/client-core/src/EventLogger.ts#L325

If this doesn't meet your needs, Statsig server SDKs provide a stronger guarantee: privateAttributes never leave your server. Server SDKs download the definition of each gate, config, and experiment and evaluate them locally.

privateAttributes stripped from event logs with the statsig-node SDK: https://github.com/statsig-io/node-js-server-sdk/blob/d1cb9431fb68b40f840254fce70363de1dc51aa5/src/LogEvent.js#L21

Evaluation happening locally to the server on privateAttributes in the statsig-node SDK: https://github.com/statsig-io/node-js-server-sdk/blob/d1cb9431fb68b40f840254fce70363de1dc51aa5/src/Evaluator.js#L374

All Statsig SDKs are open source and available on GitHub. Review the implementation of privateAttributes in the SDK you are using, or reach out on Slack for guidance.
To ensure that user PII is never transmitted over the network back to Statsig during Client SDK initialization, use Client Bootstrapping and provide the privateAttributes as part of the user object on the server to the getClientInitializeResponse(<user object>) call. This generates all of the assignments locally on your server, and you can then pass these assignments as initializeValues to the client SDK, eliminating the need to send any user attributes from the client device to Statsig.

Event logging

The SDK strips the privateAttributes field from the user object for any logEvent calls on both client and server SDKs. On server SDKs, you can omit the field from logEvent calls because no evaluation occurs at log time, so the field isn't needed. If you use the same user object throughout, the SDK handles dropping privateAttributes for you.

Was this helpful?