Skip to content

Privacy: token-follow chain creates IP-linkage across epoch transitions #312

@danmarg

Description

@danmarg

Background

When the receiver processes a transition message and ratchets to a new routing token T_new, the polling loop immediately follows the chain and polls T_new within the same poll call (up to MAX_TOKEN_FOLLOWS_PER_POLL = 5 times). This means the server sees the same client IP poll T_old and then T_new in rapid succession, creating a deterministic IP-level linkage across epoch transitions.

This is a specific instance of the IP-correlation limitation already admitted in §2.3/§7.3, but it's worth calling out separately because token rotation is designed to prevent cross-epoch correlation — and the follow-chain largely undoes that at the IP layer.

Options considered

  1. Delay to next scheduled cycle unconditionally. Never follow tokens within a single poll call; always wait for the next scheduled cycle. Cleanest from a privacy standpoint, but costs up to one full poll interval (~60s) of latency on every epoch transition. Bad UX when the user is actively watching and Alice has sent multiple updates since the last poll — the user won't see the latest location until the next cycle.

  2. Delay to next scheduled cycle if backgrounded; follow immediately if foregrounded. Helps the common case (most polling happens in the background). Requires reliable foreground/background detection threaded into the shared KMP polling logic, which currently has no app-lifecycle awareness. On iOS in particular, "background" for a location app is nuanced.

  3. Jitter the follow. Wait a random delay (0–30s) before polling T_new. Weakens the deterministic linkage without always paying a full cycle. Doesn't help if the IP is stable throughout.

  4. Accept as a known limitation. Token rotation already provides content-layer unlinkability. The IP linkage only matters for an adversary tracking a specific user's IP over time, which is already an admitted limitation. The incremental improvement from delaying token follows is marginal for most real-world threat models.

Current thinking

Option 2 is probably the right long-term answer but requires foreground detection in shared code. Option 4 (accept the limitation) is the pragmatic near-term choice given the implementation complexity and the fact that §7.3 already admits IP correlation. Option 1 is too costly to UX.

Tracking here so we can revisit when/if foreground state becomes available to the shared polling layer.

References

  • §2.3 / §7.3 (IP correlation admitted limitation)
  • §12.3 (cross-epoch correlation — content-layer only)
  • LocationClient.ktpollFriend token-follow loop, MAX_TOKEN_FOLLOWS_PER_POLL

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions