Ebook Voice Player Privacy-First Architecture: Local Parsing, Minimal Cloud, Full Data Flow Transparency
Product Link: Microsoft Store - Ebook Voice Player Introduction In an era of increasing data privacy concerns, Ebook Voice Player establishes privacy-first design principles at the architectural l
Product Link: Microsoft Store - Ebook Voice Player
Introduction
In an era of increasing data privacy concerns, Ebook Voice Player establishes privacy-first design principles at the architectural level: local document parsing, only synthesis request text hits the cloud, no account system, no telemetry, no ad tracking. This article deep-dives into its privacy architecture, data flow analysis, firewall verification guide, and how to verify privacy commitments via code audit.
1. Privacy Design Principles
| Principle | Implementation | User Value |
|---|---|---|
| Local-First | Document parsing, chapter detection, bookmarks/notes, progress memory all local | Book content never leaves device |
| Minimal Cloud | Only text-to-synthesize fragments sent to edge-tts, no metadata/identifiers | Synthesis requests unlinkable to user identity |
| No Accounts | Pure local config storage, no registration/login/cloud sync | Zero identity correlation risk |
| No Telemetry | Zero analytics/telemetry/crash reporting SDKs in codebase | Usage behavior never recorded |
| No Ad Tracking | No ad SDKs, no third-party analytics, no fingerprinting | Pure experience |
| Transparent Data Flows | Network requests only to *.azure.com / *.microsoft.com
|
Firewall-verifiable |
2. Complete Data Flow Map
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER DEVICE β
β ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββββ β
β β Document Files βββββΆβ Local Parser βββββΆβ Paragraphs (RAM) β β
β β (TXT/PDF/EPUB/ β β (reader.py) β β - Zero network β β
β β DOCX/HTML) β β - No cloud β β - Full content β β
β ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββ¬ββββββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββ β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β TTSService (Local Orchestration) β β
β β - Playback state machine β β
β β - Audio queue management β β
β β - Bookmarks/Notes/Progress (local JSON) β β
β ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββ΄βββββββββββββββββ β
β βΌ βΌ β
β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β Local Cache β β Network (HTTPS) β β
β β ~/.tts_ebook_reader/ β β *.azure.com / *.microsoft.com β β
β β audio_cache/c_<hash>.mp3 β β POST /cognitiveservices/v1 β β
β β - SHA256(content|voice|rate) - Text only β β
β β - Atomic write + validate - No user ID β β
β β - User manually clearable - No metadata β β
β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Audio Playback (Local) β β
β β - Kivy SoundLoader β SDL2 β System Audio β β
β β - Zero network during playback β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3. Core Privacy Mechanisms Deep Dive
3.1 Document Parsing: Zero Network
# reader.py - All parsers are pure local library calls
def read_txt(filepath, encoding=None):
# Pure file I/O + encoding detection, zero network requests
...
def read_pdf(filepath):
# PyMuPDF / pdfplumber pure local parsing
# Even encrypted PDFs only attempt local decryption
...
def read_epub(filepath):
# ebooklib + BeautifulSoup pure local DOM traversal
# EPUB internal resources (images/CSS/fonts) only read, never uploaded
...
def read_docx(filepath):
# python-docx pure local XML parsing
...
Verification: Disconnect network, open any format document β all parse, show chapters, jump paragraphs normally.
3.2 Synthesis Requests Minimized
# tts_engine.py - TTSGenerator.gen_one()
async def gen_one(idx, text):
# Only sends: text content + voice ID + rate
# Does NOT send: filename, chapter name, user settings, device info, identifiers beyond IP
communicate = edge_tts.Communicate(text, self.voice, rate=rate_str)
await communicate.save(str(tmp_file))
Request Payload Analysis:
POST https://<region>.tts.speech.microsoft.com/cognitiveservices/v1
Headers:
- Authorization: Bearer <short-lived token> (edge service auto-fetches, no user credentials)
- Content-Type: application/ssml+xml
- X-Microsoft-OutputFormat: audio-24khz-48kbitrate-mono-mp3
Body (SSML):
<speak version='1.0' xml:lang='zh-CN'>
<voice xml:lang='zh-CN' xml:gender='Female' name='zh-CN-XiaoxiaoNeural'>
<prosody rate='+10%'>Chapter One Content...</prosody>
</voice>
</speak>
Key Points:
- No cookies, no User-Agent identifying user
- Token auto-fetched by edge-tts from public endpoint, not user login state
- Same paragraph + same voice + same rate β same cache key β repeat request hits local cache, zero network
3.3 Local Storage: Only Config & Progress
# main_screen.py - save_settings()
def save_settings(self):
data = {
"font_size": self.font_size,
"line_spacing": self.line_spacing,
"page_margin": self.page_margin,
"dark_mode": self._dark,
"ui_lang": get_language(), # UI language preference only
"recent_files": self.recent_files, # Local file path list
"bookmarks": self.bookmarks, # {file, paragraph, label}
"annotations": self.annotations, # {paragraph: note_text}
"reading_stats": { # Aggregate counters only
"total_sec": self._stats["total_sec"],
"total_paras": self._stats["total_paras"],
},
"last_file": self._last_file, # Last opened file path
"last_position": self._last_position, # {file, paragraph}
}
# Storage: %APPDATA%\EbookVoicePlayer\settings.json (Windows)
# or ~/.config/EbookVoicePlayer/settings.json (Linux/Android)
with open(self._settings_path(), "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
Storage Content Inventory:
| Field | Meaning | Sensitivity |
|---|---|---|
font_size etc |
UI preferences | None |
recent_files |
Local path list | Low (readable only on this machine) |
bookmarks |
Bookmark position+label | Low (user-created) |
annotations |
Note text | Medium (user input) |
reading_stats |
Total time/paragraphs | None |
last_file/position |
Resume position | Low |
NOT Stored: Book full text, synthesized audio (separate cache dir), network identity, usage timestamp sequences.
3.4 Cache Isolation & User Control
# tts_engine.py - get_cache_dir() & cleanup()
def get_cache_dir():
app = App.get_running_app()
if app is not None:
base = Path(app.user_data_dir) # System-assigned app private dir
else:
base = Path.home() / ".tts_ebook_reader"
d = base / "audio_cache"
d.mkdir(parents=True, exist_ok=True)
return d
def cleanup(self):
"""User manual cleanup / auto on uninstall"""
for f in get_cache_dir().glob("*.mp3"):
try:
f.unlink()
except OSError:
pass
self._stale = []
Cache Properties:
- In app sandbox directory, inaccessible to other apps
- Filenames
c_<SHA256-first16>.mp3, content not inferable from name - User can one-click clear via menu "Tools β Clear Audio Cache"
- Uninstall auto-clears sandbox directory
4. Network Allowlist & Firewall Verification
4.1 Only Permitted Outbound Domains
| Domain Pattern | Purpose | Protocol/Port |
|---|---|---|
*.azure.com |
edge-tts synthesis endpoints | HTTPS/443 |
*.microsoft.com |
Token fetch, CDN | HTTPS/443 |
4.2 Windows Firewall Verification Script
# 1. Create allow rule for only above domains
New-NetFirewallRule -DisplayName "EbookVoicePlayer Allow TTS" `
-Direction Outbound -Action Allow `
-Program "C:\Program Files\WindowsApps\nannan2008.EbookVoicePlayer_*\TTSReader.exe" `
-RemoteAddress (Resolve-DnsName "*.azure.com", "*.microsoft.com" -Type A).IPAddress
# 2. Block all other outbound
New-NetFirewallRule -DisplayName "EbookVoicePlayer Block Other" `
-Direction Outbound -Action Block `
-Program "C:\Program Files\WindowsApps\nannan2008.EbookVoicePlayer_*\TTSReader.exe" `
-RemoteAddress Any
# 3. Verify: Wireshark capture shows ONLY TTS requests
# Filter: http.host contains "azure" or http.host contains "microsoft"
4.3 Wireshark Capture Expected Results
Normal session contains ONLY:
1. DNS query: <region>.tts.speech.microsoft.com
2. TLS handshake (TLS 1.2/1.3)
3. HTTP/2 POST /cognitiveservices/v1 (SSML body)
4. HTTP/2 200 OK (MP3 binary response)
5. Zero network during playback
Anomaly indicators (MUST NOT appear):
β Any analytics/telemetry endpoints
β Any ad/tracking domains
β Any non-azure/microsoft domains
β Any non-443 port connections
β Any periodic heartbeat/reporting traffic
5. Code Audit Guide: Verifying Privacy Commitments
5.1 Keyword Search Checklist
# 1. Search network library imports
grep -r "requests\|httpx\|aiohttp\|urllib\|socket" --include="*.py" .
# Expected: ONLY in tts_engine.py via edge_tts indirect usage
# 2. Search telemetry/analytics keywords
grep -ri "telemetry\|analytics\|tracking\|metrics\|sentry\|crashlytics\|firebase\|amplitude\|mixpanel" --include="*.py" .
# Expected: ZERO matches
# 3. Search ad SDKs
grep -ri "admob\|adsense\|unityads\|applovin\|chartboost\|vungle\|ironsource" --include="*.py" .
# Expected: ZERO matches
# 4. Search account/auth related
grep -ri "oauth\|login\|register\|account\|password\|token\|jwt\|api_key" --include="*.py" .
# Expected: ONLY edge-tts internal token handling, no user auth flows
# 5. Search data upload
grep -ri "upload\|sync\|backup\|cloud\|remote.*config" --include="*.py" .
# Expected: ZERO matches
5.2 Dependency Audit
# requirements.txt
edge-tts==6.1.9
kivy==2.3.0
python-docx==1.1.0
PyMuPDF==1.23.0
pdfplumber==0.10.0
ebooklib==0.18
beautifulsoup4==4.12.0
lxml==4.9.0
# Audit Points:
# - NO requests/httpx direct HTTP libs (edge-tts uses aiohttp internally)
# - NO telemetry/analytics packages
# - NO ad SDK dependencies
# - All deps are well-known open-source, source auditable
5.3 Runtime Behavior Audit
# Monitor network connections at startup (Windows)
# Use TCPView / Resource Monitor / Wireshark
# 1. Launch app β ZERO network connections established
# 2. Open local EPUB β ZERO network connections
# 3. Click Play β Establish TLS to *.azure.com:443
# 4. Pause/Stop β Connection held or closed, no new connections
# 5. Switch voice/rate β New synthesis connections, old reused
# 6. Idle 10 minutes β ZERO heartbeat connections
# 7. Close app β All connections closed
6. Comparison: Typical Privacy Risks vs This App's Countermeasures
| Risk | Typical App Approach | Ebook Voice Player Countermeasure |
|---|---|---|
| Book Content Upload | Cloud parsing/sync progress | Pure local parsing, progress only in local JSON |
| User Profiling | Collect reading prefs/duration/book metadata | Zero reporting, stats stay local |
| Third-Party Tracking | Integrate Firebase/Adjust/UMeng | Zero third-party SDKs |
| Ad Serving | Interstitial/banner/native ads | Zero ad code, zero ad slots |
| Forced Account Binding | Must login to use | No account system, works out of box |
| Data Export Hard | Cloud lock-in, export restricted | Config/bookmarks/notes all local JSON, copy anytime |
| Uninstall Residue | Registry/cloud data retained | Sandbox dir auto-cleared on uninstall |
| Synthesis Content Leak | Server logs full text | Only edge service transient processing, no persistent logs (Microsoft privacy terms) |
7. Enterprise/Sensitive Deployment Guide
7.1 Fully Offline Mode (Air-gapped/Classified Environments)
# 1. Pre-warm cache: batch synthesize needed chapters in connected env
# - Open book β Select all β Export MP3 (Menu: Tools β Export to Audio Files)
# - After export, cache dir contains all paragraph audio
# 2. Offline deploy: Copy installer + cache dir to target machine
# - Install app
# - Copy cache dir to %APPDATA%\EbookVoicePlayer\audio_cache\
# 3. Offline use: Fully disconnected
# - Open book β Parsing works
# - Play β Reads cached MP3 directly, ZERO network
# - Bookmarks/notes/progress β All local save
7.2 Firewall Policy Template
# Enterprise firewall/proxy policy example
rules:
- name: "EbookVoicePlayer TTS Allow"
action: allow
app: "TTSReader.exe"
dst_domains:
- "*.azure.com"
- "*.microsoft.com"
dst_ports: [443]
protocol: tcp
- name: "EbookVoicePlayer Default Deny"
action: deny
app: "TTSReader.exe"
dst: any
log: true
8. Compliance Statement
| Compliance Dimension | Status | Notes |
|---|---|---|
| GDPR | Compliant | No personal data collected, no data subject rights scenarios |
| CCPA | Compliant | No sale of personal info, no tracking |
| China PIPL | Compliant | No personal information processing activities |
| Microsoft Store Policy | Compliant | Certified & published, privacy policy public |
| COPPA | Compliant | No collection of under-13 data |
Privacy Policy: privacy.html
9. Future Privacy Enhancement Roadmap
- [ ] Local TTS Engine Integration (Piper/Coqui) - Fully offline synthesis, zero cloud dependency
- [ ] E2E Encrypted Sync (Optional) - WebDAV encrypted sync of bookmarks/progress, user-held keys
- [ ] Differential Privacy Stats (Optional) - Local aggregation then fuzzy reporting, fully user-disableable
- [ ] Audit Log Export - One-click export of all app network requests for compliance audit
10. Conclusion
Ebook Voice Player delivers privacy commitments via code-as-contract:
- Architectural Isolation: Parsing/playback/storage all local, only minimal synthesis text to cloud
- Code Transparency: Zero telemetry, zero ads, zero accounts, auditable dependencies
- Runtime Verifiable: Firewall allowlist, Wireshark capture, offline test all pass
- User Control: Cache clearable, config exportable, uninstall leaves no residue
In the "data is asset" era, choosing a tool that doesn't treat your reading as a product is basic self-respect for privacy.
Try It: Microsoft Store - Ebook Voice Player
Source Audit: GitHub - Fully Auditable Python Source
Privacy Policy: Read Online
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.