Using Private Attributes
Evaluating feature gates, dynamic configs, segments, and experiments without logging user data to Statsig
We take privacy, and the privacy of your user data, very seriously. If you have legal requirements that prevent you from sending PII to third parties, or you are just uncomfortable sending PII to a third party service, it is still possible to use Statsig for feature gating, configs, or experiments.
How It Works
Any field you wish to evaluate on can be made private. Note that if you make the userID field private, your experience in the Statsig console will be broken (the user's tab, metrics charts, event logs, and pulse metrics will be unable to populate accurately). If you wish to hide the UserID, we recommend you use a stable, one-way hash to maintain the ability to analyze user behavior.
For example, let's say you want to use an email condition:
- Create a feature gate with a condition that passes on certain emails or domains
- Pass
email: email@domain.com
inprivateAttributes
rather than in the top levelemail
field - Test it out in the
Test Gate
console after saving changes
When evaluating rules and conditions, Statsig first checks for fields at the top level, then in the custom attributes, and finally, in the private attributes. By simply not passing email at the top level, the evaluator will keep looking in other possible places before evaluating the condition (custom
, and then privateAttributes
).
So if you want to keep the ip address and user agent private, but still use browser or IP checks in the console, simply put them in the privateAttributes
dictionary instead of at the top level of the user. The same goes for country, locale, custom fields, and so on.
Our statsig-node SDK illustrates how this works (and is exactly how we evaluate gates on our servers as well): https://github.com/statsig-io/node-js-server-sdk/blob/d1cb9431fb68b40f840254fce70363de1dc51aa5/src/Evaluator.js#L374
Do not provide a privateAttribute
key anywhere else in the user
object. The entire privateAttributes
dictionary is dropped, but any duplicate fields at the top level or in the custom object will still be logged (and evaluated against)