Skip to main content
Targeting is how FireWeave decides which value a control point returns for a given identity. A target is that identity — a user or device keyed by targetingKey — optionally carrying durable properties stored by fw-server. You own the ID. The SDK never auto-generates one. OpenFeature and the wire still say flagKey for the control point. Identity on that call is always targetingKey.

Why it exists

Percentage assignment hashes (flag, targetingKey). If the key changes every request, users flip variants and the backend fills with junk persons. Registration exists so durable facts (plan, region, device model) do not have to ride on every evaluate.

When to use it

user, org, plan, and region are not reserved SDK fields. kind on register is only 'user' | 'device'. plan and region appear in SDK identity docs as example property names you may send — you choose the keys.
Anti-patterns: a fresh UUID per request, request IDs, timestamps, or a targetingKey you would not send as an analytics person identifier. Prefer opaque IDs over email addresses. The SDK forwards the key verbatim and does not hash or rotate it.

How it relates

Identity rules

  1. Never auto-generated. No targetingKey means no invented anonymous ID.
  2. Missing key fails safe on backend evaluation: your default + TARGETING_KEY_MISSING (InvalidContext).
  3. requireTargetingKey defaults to false in the four server SDKs. Set it true if you want keyless calls rejected even in tests.
In-memory evaluation of unconditional fixtures may succeed without a key unless you opt into that strictness.

Two identity paths

These compose; they do not compete.
  1. registerTarget / identify — durable properties stored by fw-server (POST /v1/targets/register). Call once per login or device provisioning.
  2. Per-evaluate attributes — win for that call. Use for request-only facts.
$-prefixed attributes are backend system directives, not person properties. fw_-prefixed target property keys are reserved and stripped server-side.
Whether fw-server persists properties in production, and which predicates it evaluates, is platform-side and NEEDS VERIFICATION. The SDK forwards targetingKey, attributes, groups, and groupProperties.

Registration lifecycle

Registration is idempotent: re-register updates properties. It never throws — login paths must not break. Adapters without the capability (InMemory, local/dev) return ok: false with UnsupportedCapability.
Do not document Go or Java registration. A local Java parity branch is not master. The protocol spec line that says “Node only” is stale — Python and Web implement it.
The test-server stub does not implement POST /v1/targets/register. Register tests use mocks or an injected fetch, not that stub.

What it looks like

Groups

Group membership and group properties travel on the evaluation context. Canonical keys: fireweave.groups and fireweave.groupProperties. Plain groups / groupProperties are accepted aliases; canonical keys win if both are present. Any other fireweave.* context key is rejected with InvalidContext. targetingKey and kind are also reserved in the evaluation context.
Java also has builder helpers .group(...) / .groupProperty(...). Group identify (creating group profiles) is not a FireWeave extension. Do that with your analytics SDK if you need it.

Privacy (what the SDK actually does)

Evidenced in the SDK privacy review — not a console policy:
  • The SDK adds no person properties of its own. Whatever you put on the context is forwarded to fw-server (or a vendor adapter where one still exists).
  • Prefer derived attributes (email_domain) over raw PII if you must target on identity-adjacent facts.
  • Error messages are secret-redacted and must not echo attribute values.
  • Signal attributes pass an allowlist. Evaluation context is not that allowlist — evaluate forwards what you send (minus reserved keys).
  • Nothing is persisted to disk by the SDK.
Which targeting predicates fw-server runs is NEEDS VERIFICATION.
Last modified on August 18, 2026