Skip to content

Sanitize hostname metadata from Research Edition exports - #1408

Merged
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:bob/research-export-hostname-sanitize
Aug 26, 2026
Merged

Sanitize hostname metadata from Research Edition exports#1408
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:bob/research-export-hostname-sanitize

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Summary

Research Edition /api/0/export currently copies the machine hostname into every bucket's map key, embedded id, and hostname field. On a named laptop that is a participant identifier. The live Research filter already rewrites event app/title/url; it never touched bucket identity.

This adds a Research-build-only patch at the Rust export boundary (same injection style as patch_research_edition_config.py). Standard builds do not run the patcher.

  • Rewrite outer key, id, and hostname together to research-participant.
  • Fail closed (HTTP 409) if two source buckets collapse to one sanitized ID.
  • Fail closed if currentwindow events still carry raw titles/URLs/app names, so an existing ActivityWatch database cannot look study-safe.
  • Event payloads are unchanged.

Measured against the published v0.14.0b4-research window + AFK watchers under a UTS hostname Participant-Alice-MacBook: unpatched export had 6 hostname occurrences; the patched server had 0. Unpatched current-source server still leaks (negative control).

Tauri remains out of scope for the September participant path.

Test plan

  • pytest scripts/tests/test_patch_research_edition_export.py
  • cargo test -p aw-server --lib sanitize after applying the patch
  • Existing test_import_export still passes on the patched tree
  • Packaged Qt watchers + rebuilt rust server: 0 hostname occurrences; standard/unpatched still leaks
  • CI research-edition job applies the patch and builds

Watchers store buckets as {client}_{hostname}. /api/0/export copied that
machine name into the map key, embedded id, and hostname field — six leaks
per window+AFK pair on a named laptop. Patch the Rust export path only when
AW_RESEARCH_EDITION=true so standard builds stay unchanged. Fail closed on
sanitized-ID collisions and on unfiltered historical window events.
@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds a Research Edition-only build patch that sanitizes bucket hostname metadata at both Rust export endpoints and rejects ambiguous or apparently unfiltered exports.

  • Applies the sanitizer before Qt and Tauri Research Edition builds.
  • Rewrites bucket map keys, embedded IDs, and hostname fields consistently.
  • Returns HTTP 409 for identity collisions or disallowed raw event metadata.
  • Adds patcher and sanitizer coverage, including live-tree compatibility checks.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code failure established on the supported Research Edition export path.

The release workflow patches the Rust source before compilation, the patcher fails when expected insertion points are unavailable, and the sanitizer keeps the exported map key, embedded ID, and hostname aligned while rejecting collisions.

Important Files Changed

Filename Overview
.github/workflows/release.yml Adds Research-only sanitizer patch steps before the relevant build steps in both release jobs.
scripts/patch_research_edition_export.py Adds an idempotent, fail-closed source patcher that injects the sanitizer into both Rust export endpoints.
scripts/research_edition/export_sanitize.rs Validates exported event metadata and consistently replaces bucket hostname identity while rejecting collisions.
scripts/tests/test_patch_research_edition_export.py Covers patch insertion, idempotence, missing markers, live-tree compatibility, and category allowlist synchronization.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Research Edition release job] --> B[Patch Rust export endpoints]
    B --> C[Build Rust server]
    C --> D[Client requests export]
    D --> E[Load exported buckets]
    E --> F{Unfiltered event data?}
    F -- Yes --> G[HTTP 409]
    F -- No --> H[Rewrite key, ID, and hostname]
    H --> I{Sanitized identity collision?}
    I -- Yes --> G
    I -- No --> J[Return sanitized export]
Loading

Reviews (1): Last reviewed commit: "feat(research): sanitize hostname metada..." | Re-trigger Greptile

@ErikBjare
ErikBjare merged commit 991d906 into ActivityWatch:master Aug 26, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants