Repository navigation
feat(browser): support flag-key obfuscation - #405
Conversation
OpenFeature Browser Provider Bundle SizesMeasured from the Vite production output after installing packed Both scenarios initialize an OpenFeature provider, evaluate a boolean flag, change context, and evaluate again. Telemetry is disabled for DatadogProvider; no tracking hooks are registered for DatadogCoreProvider. DatadogProvider fetches precomputed assignments for each context; DatadogCoreProvider receives rules from fetchRulesConfiguration once and evaluates locally. Sizes include OpenFeature and the same small scenario harness. Configuration responses are supplied by Playwright and are not bundled. These are complete scenario JS sizes, not configuration payload sizes or isolated provider/Protobuf costs; the difference between rows is not a decoder-only delta.
Dependency checks passed: no Protobuf markers in default/precomputed scenarios; markers present in rules-based scenarios. OpenFeature Browser Tracking Hook Bundle SizesSynthetic entrypoints import and call tracking hook factories from the packed
This report shows current PR artifact sizes only; it does not compare against the base branch. |
aarsilv
left a comment
There was a problem hiding this comment.
Thanks for iterating! 🚀 Just a few nits left you can take or leave as you see fit!
Tracking: FFLSDK-262
Motivation
Readable flag keys can reveal upcoming features. Support obfuscated assignments without changing application evaluation calls.
This reduces readable names in payloads; it does not hide values or prevent dictionary guessing. It is not encryption or response signing.
Changes and Decisions
Advertise support through this header instead of a JSON
supported_capabilitiesfield. Existing request fields stay unchanged.X-DD-FEATURE-FLAGS-CAPABILITIES: assignment-encoding-flag-key-256-v1The SDK adds this header automatically only for Datadog endpoints. Requests through
flaggingProxyomit it unless the application supplies it incustomHeaders. Cross-origin proxies must allow it in CORS before opting in.Capabilities are sorted and comma-separated. They describe support, not a requirement. The edge still selects plaintext or obfuscated responses through its rollout.
For
obfuscated: true, validateobfuscation: {scheme, salt}and hash the application key for lookup. The response scheme remainsflag-key-sha256-v1:The public salt contains 16 bytes, encoded as 32 lowercase hexadecimal characters. Keys use exact UTF-8 bytes without normalization.
sequenceDiagram participant App participant SDK as Browser provider and shared core participant Edge as Fastly SDK->>Edge: Precompute request + capability header Edge-->>SDK: Plaintext, or encoded keys + scheme + salt SDK->>SDK: Validate and retain assignments with encoding App->>SDK: Evaluate original flag key SDK->>SDK: Hash lookup key only for encoded assignments SDK-->>App: Original value and evaluation details SDK->>SDK: Keep original flag key in telemetrycreatedAtchanges. The core provider uses configuration identity.createdAtis a configuration timestamp, not an experiment revision. Same-configuration deduplication and the online provider's first-fetch exception remain unchanged.STALE. Without usable cached assignments, reject initialization and reportERROR. Do not retry without the capability.Failed context-switch behavior remains separate: FFLSDK-255.
Release only after ddoghq/dd-source#121201 is deployed to every site this SDK targets. Before releasing, verify that each site's OPTIONS response allows
X-DD-FEATURE-FLAGS-CAPABILITIES. Browsers block assignment requests until that CORS change is live. This PR does not deploy backend changes.Related: edge rollout, documentation.
Validation
Nine Chromium smoke tests passed against packed packages and local HTTP fixtures. They covered header negotiation, salt changes, offline restoration of the latest value, plaintext rollback, and operation without Web Crypto or native text encoders.
A compatibility check executed the previous reader from
mainat9f198f1against new cache entries and portable snapshots. It retained access to legacy plaintext, missed new encoded cache entries, and rejected encoded version-2 snapshots.These checks did not use staging.