Slack thread
Problem
The Onyx state export (Settings → Troubleshoot → Export Onyx state) uses a hand-maintained allow/mask rule table (ONYX_KEY_EXPORT_RULES in src/libs/ExportOnyxState/common.ts) to decide which fields are exported as-is vs. masked.
Only 12 Onyx keys / collection prefixes have explicit rules. The remaining ~100+ keys either:
- Fall back to a heuristic
maskFragileData pass (when the mask toggle is on), or
- Are exported fully unmasked (when the mask toggle is off)
This means:
- Useful debug data is often masked or mangled — when
maskFragileData runs on an un-ruled key, numbers are randomized, strings that happen to match keysToMask field names are masked, and structured objects lose their values. Exported files shared with support are frequently not reproducible.
- No enforcement — there is nothing to remind engineers to add a rule when a new Onyx key is introduced. The gap silently grows with every new feature.
COLLECTION.REPORT_ACTIONS has no rule — one of the highest-value collections for debugging is processed only by heuristics, not an explicit rule.
Background
The export system has three layers:
-
ONYX_KEY_EXPORT_RULES — a hand-maintained Record<string, ExportRule> where each entry has an allowList (fields kept as-is) and a maskList (fields length-masked). Any field not on either list is still transformed: numbers randomized, dates replaced, strings masked, objects recursed. Currently covers: SESSION, STASHED_SESSION, CREDENTIALS, STASHED_CREDENTIALS, ACCOUNT, PERSONAL_DETAILS_LIST, COLLECTION.REPORT, COLLECTION.TRANSACTION, COLLECTION.POLICY, USER_WALLET, BANK_ACCOUNT_LIST, CARD_LIST.
-
onyxKeysToRemove — a hard-coded Set of truly private keys (auth tokens, Onfido IDs, Plaid tokens, all DERIVED keys) that are stripped before any processing.
-
maskFragileData — a recursive heuristic pass applied to all keys without an export rule (when the mask toggle is on). Uses a keysToMask set of ~35 field names, an amountKeysToRandomize set, and email-regex scanning. This is the fallback for all un-ruled keys.
ONYXKEYS.COLLECTION alone has 50+ prefixes; only 3 have explicit rules. Notable gaps:
COLLECTION.REPORT_ACTIONS — message text/HTML only partially caught by maskFragileData
COLLECTION.TRANSACTION_VIOLATIONS — useful for debugging, no rule
COLLECTION.NEXT_STEP — report next step for debugging approval flows, no rule
COLLECTION.REPORT_METADATA — optimistic flags, error state, no rule
COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS — workspace config, generally safe, no rule
Goal
Audit all ONYXKEYS (top-level and COLLECTION.*) and for each one explicitly decide:
| Category |
Action |
| Contains PII / sensitive data |
Add an entry to ONYX_KEY_EXPORT_RULES with an explicit allowList and maskList |
| Completely safe to export as-is |
Add it to ONYX_KEY_EXPORT_RULES with a full allowList |
| Should never leave the device |
Add to onyxKeysToRemove |
Then add a lint rule or TypeScript-level check so every new ONYXKEYS entry must have a corresponding entry in one of the three buckets — making the coverage self-maintaining going forward.
Acceptance Criteria
Files to Change
src/libs/ExportOnyxState/common.ts — primary change target
src/ONYXKEYS.ts — reference for all keys
- Possibly a new ESLint rule or type mapping in
src/types/onyx/
Issue Owner
Current Issue Owner: @mkhutornyi
Slack thread
Problem
The Onyx state export (Settings → Troubleshoot → Export Onyx state) uses a hand-maintained allow/mask rule table (
ONYX_KEY_EXPORT_RULESinsrc/libs/ExportOnyxState/common.ts) to decide which fields are exported as-is vs. masked.Only 12 Onyx keys / collection prefixes have explicit rules. The remaining ~100+ keys either:
maskFragileDatapass (when the mask toggle is on), orThis means:
maskFragileDataruns on an un-ruled key, numbers are randomized, strings that happen to matchkeysToMaskfield names are masked, and structured objects lose their values. Exported files shared with support are frequently not reproducible.COLLECTION.REPORT_ACTIONShas no rule — one of the highest-value collections for debugging is processed only by heuristics, not an explicit rule.Background
The export system has three layers:
ONYX_KEY_EXPORT_RULES— a hand-maintainedRecord<string, ExportRule>where each entry has anallowList(fields kept as-is) and amaskList(fields length-masked). Any field not on either list is still transformed: numbers randomized, dates replaced, strings masked, objects recursed. Currently covers:SESSION,STASHED_SESSION,CREDENTIALS,STASHED_CREDENTIALS,ACCOUNT,PERSONAL_DETAILS_LIST,COLLECTION.REPORT,COLLECTION.TRANSACTION,COLLECTION.POLICY,USER_WALLET,BANK_ACCOUNT_LIST,CARD_LIST.onyxKeysToRemove— a hard-codedSetof truly private keys (auth tokens, Onfido IDs, Plaid tokens, allDERIVEDkeys) that are stripped before any processing.maskFragileData— a recursive heuristic pass applied to all keys without an export rule (when the mask toggle is on). Uses akeysToMaskset of ~35 field names, anamountKeysToRandomizeset, and email-regex scanning. This is the fallback for all un-ruled keys.ONYXKEYS.COLLECTIONalone has 50+ prefixes; only 3 have explicit rules. Notable gaps:COLLECTION.REPORT_ACTIONS— message text/HTML only partially caught bymaskFragileDataCOLLECTION.TRANSACTION_VIOLATIONS— useful for debugging, no ruleCOLLECTION.NEXT_STEP— report next step for debugging approval flows, no ruleCOLLECTION.REPORT_METADATA— optimistic flags, error state, no ruleCOLLECTION.POLICY_CATEGORIES,COLLECTION.POLICY_TAGS— workspace config, generally safe, no ruleGoal
Audit all
ONYXKEYS(top-level andCOLLECTION.*) and for each one explicitly decide:ONYX_KEY_EXPORT_RULESwith an explicitallowListandmaskListONYX_KEY_EXPORT_RULESwith a fullallowListonyxKeysToRemoveThen add a lint rule or TypeScript-level check so every new
ONYXKEYSentry must have a corresponding entry in one of the three buckets — making the coverage self-maintaining going forward.Acceptance Criteria
ONYXKEYS(flat keys) andONYXKEYS.COLLECTIONhas a deliberate entry in eitherONYX_KEY_EXPORT_RULESoronyxKeysToRemoveCOLLECTION.REPORT_ACTIONShas an explicit export rule covering fields needed to reproduce bugs (action type, timestamp, accountID, pendingAction, errors) with message text/HTML on the mask listmaskFragileDataheuristic is either retired or kept only as a last-resort fallback for truly unknown structuresFiles to Change
src/libs/ExportOnyxState/common.ts— primary change targetsrc/ONYXKEYS.ts— reference for all keyssrc/types/onyx/Issue Owner
Current Issue Owner: @mkhutornyi