data privacy & security policy

ScribeFloat handles
no data centrally.

Version 1.0 · Last updated 2026-05-05 · Written for security officers, IT auditors, and compliance teams.

QuestionAnswer
Does the app send audio to any server?No — never
Does the app send transcripts to any server?No — never
Does the app require an account or login?No
Does the app collect telemetry or analytics?No
Does the app phone home for updates?No — but "Check for updates" in Settings → Help makes a single opt-in request to api.github.com if the user clicks the button
Does the app require an always-on internet connection?No
Is an internet connection ever required?Yes — once to download a Whisper transcription model, and optionally once to download the Silero VAD model (~2 MB). Both are user-initiated. Optionally when the user manually clicks "Check for updates".
Where is all user data stored?Exclusively on the user's local device
What AI model runs the transcription?OpenAI Whisper (ggml format), running locally
Does the AI model phone home?No — inference is fully offline
What OS permissions are required?Microphone (all platforms), Accessibility (macOS only for paste), Input Monitoring (macOS only for hotkey)
Can the app be used fully offline after setup?Yes

This document is written for security officers, IT auditors, and compliance teams evaluating whether ScribeFloat can be deployed in their environment. It is intentionally comprehensive and direct.

1. Network activity

1.1 Outbound requests

The application makes at most two types of outbound network requests.

Request 1 — Model download

HTTP GETs to huggingface.co, each initiated only when the user explicitly clicks a download button in Settings → Models.

There are two distinct model types:

ModelSourceSizePurpose
Whisper transcription modelhuggingface.co/ggml-org/75 MB – 1.5 GB depending on variantSpeech-to-text inference (Scribe, Dictate, Transcribe)
Silero VAD modelhuggingface.co/ggml-org/whisper-vad~2 MBVoice activity detection — skips silence during transcription

Both downloads share the same attributes:

AttributeDetail
Destinationhttps://huggingface.co
When it occursOnly on explicit user action. Never automatically on launch.
Account requiredNo
What is sent to Hugging FaceAn HTTP GET request. No user data, audio, or identifiers are sent in the request body. Standard HTTP headers only.
ProtocolHTTPS with certificate verification via rustls-tls
After downloadModel files are stored locally in the app-data models/ directory. No further contact with Hugging Face occurs.

Request 2 — Update check (opt-in, user-initiated only)

AttributeDetail
Destinationhttps://api.github.com
What is fetchedLatest release metadata: version string, release notes, release URL. No binary is downloaded automatically.
When it occursOnly when the user explicitly clicks "Check for updates" in Settings → Help. Never automatically on launch or in the background.
What is sentAn HTTP GET request. User-Agent: scribefloat/<version> header. No audio, no transcripts, no personal data.
ProtocolHTTPS with certificate verification via rustls-tls
After fetchIf a newer version is found, a banner is shown with a "Open download page" button that opens the browser. Nothing is downloaded or installed automatically.

1.2 No automatic network connections

The application makes no automatic network connections of any kind. There is no:

  • Analytics or telemetry endpoint
  • Crash reporting service
  • Licence validation server
  • Background update check (the update check in Settings → Help is manual and user-initiated only)
  • WebSocket or long-lived connection
  • DNS resolution for any domain other than huggingface.co and (optionally) api.github.com on explicit user action

The Tauri WebView's Content Security Policy enforces this at the browser layer:

default-src 'self' asset: https://asset.localhost;
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' asset: https://asset.localhost data:;
connect-src 'self' ipc: http://ipc.localhost;

1.3 Network verification steps for auditors

  1. Run the app with a packet capture tool (e.g. Wireshark, Little Snitch, Windows Firewall log)
  2. Use all features: open Scribe, record, transcribe, open Dictate, use Settings
  3. Confirm the only DNS queries and TCP connections are to huggingface.co and only when you explicitly initiate a model download

2. Audio handling

2.1 Microphone access

  • Required for Scribe (recording sessions) and Dictate (voice-to-text)
  • The OS presents a permission prompt on first use; the app does not bypass or pre-grant this
  • Audio is captured in raw PCM format via cpal, a cross-platform audio library
  • Captured audio is held in-process memory and written to disk only by OutputService

2.2 System audio (speaker capture)

  • Optional — only active if the user explicitly enables the "Speaker capture" toggle in Scribe
  • macOS: captured via BlackHole virtual audio device, which must be separately installed by the user. BlackHole is an open-source virtual audio driver; ScribeFloat does not bundle or install it automatically.
  • Windows: captured via WASAPI loopback (built into Windows; no additional software required)
  • No additional OS permission is needed beyond what BlackHole or WASAPI provides

2.3 Dictate audio — memory only, never on disk

This is the most security-relevant audio-handling characteristic of the Dictate feature:

Dictate audio is never written to disk under any circumstance.

The audio buffer is allocated in process memory when the hotkey is pressed and released immediately after Whisper inference completes. There is no temporary file, no swap-to-disk path, and no audio log. This is enforced by code architecture: OutputService (the only component permitted to write files) is never called during a Dictate session. The Dictate controller passes its PCM buffer directly to ModelService for inference, then discards it.

2.4 Scribe and Transcribe audio lifecycle

StageScribe (user records)Transcribe (user drops file)
Audio written to diskYes — mic.wav (and speaker.wav if dual-source)No — user's source file is read but not copied
Written byOutputService onlyN/A
Deleted after transcriptionYes — automatically, once the transcript is confirmed written and non-emptyN/A — user owns source file
Deleted byOutputService only, after verifying transcript exists and is non-emptyN/A
Location while on diskUser-configured save folderN/A

3. OS permissions

3.1 Permission table

PermissionPlatformPurposeConsequence of denial
MicrophonemacOS + WindowsCapture audio for Scribe and DictateScribe and Dictate cannot record; Transcribe (file import) still works
AccessibilitymacOS onlySimulate Cmd+V to paste dictated text into the focused appDictate falls back to copying text to clipboard + showing a system notification; no paste injection
Input MonitoringmacOS onlyDetect global keyboard events for Dictate hotkeyDictate hotkey does not trigger; Scribe hotkey also affected

3.2 How permissions are used

Microphone: The OS audio framework is queried to open a capture stream. The app calls PermissionsService::statuses() to check the current grant status and shows the result in Settings → Dependencies. It does not attempt to access the microphone unless the user initiates a recording action.

Accessibility (macOS): Used exclusively to simulate a paste keystroke (Cmd+V) via the macOS Accessibility API after Dictate transcription completes. The app does not read any other application's UI elements, read clipboard contents of other apps, or observe any other accessibility data. The paste simulation is implemented in platform/paste_impl.rs.

Input Monitoring (macOS): Used to register a CGEventTap that listens for modifier key state changes (key down / key up on the configured Dictate trigger key). The tap reads raw keycode values only — it does not perform string conversion, does not log keystrokes, and does not inspect non-modifier keys. The implementation is in platform/key_listener.rs.

3.3 Revoking permissions

All permissions can be revoked at any time via:

  • macOS: System Settings → Privacy & Security → [Microphone | Accessibility | Input Monitoring]
  • Windows: Settings → Privacy & Security → Microphone

Revoking a permission does not delete any existing data. The affected feature degrades gracefully (Scribe/Dictate cannot record; Dictate falls back to clipboard).

4. Local data storage

4.1 Storage locations

DataLocationFormat
App configurationOS app-data dir (config.json)JSON
Whisper model filesOS app-data dir (models/)Binary (ggml)
TranscriptsUser save folder (default: ~/Documents/ScribeFloat/)Markdown (.md)
Audio recordingsUser save folder, inside per-session subfoldersWAV
Dictate history logUser save folder (dictate.jsonl)JSONL
Dictate audio bufferRAM onlyIn-process memory

OS app-data directories:

  • macOS: ~/Library/Application Support/com.benjamin.scribefloat-v8/
  • Windows: %APPDATA%\com.benjamin.scribefloat-v8\

4.2 Config file contents

config.json stores only user preferences and paths. It never contains audio data, transcript content, or credentials. Fields include:

  • save_folder — path to transcript output directory
  • open_scribe_hotkey, dictate_hotkey — hotkey strings (stored in config; not currently editable via the Settings UI)
  • selected_model_id, dictate_model_id, scribe_model_path — local model file paths
  • include_timestamps — whether transcripts include timestamps
  • keep_wav — whether WAV recordings are retained after transcription (default: deleted)
  • scribe_capture_speaker — whether speaker capture is enabled
  • preferred_input_device, preferred_speaker_device — audio device names
  • input_label, output_label — display labels for the two Scribe audio sources
  • theme_mode — UI theme preference
  • open_with_app_path — application used to open completed transcripts (macOS: app name; Windows: full exe path)
  • dictate_auto_paste, dictate_auto_enter — Dictate behaviour flags
  • replacement_rules — user-defined spoken-phrase-to-text substitution rules (e.g. "new line" → newline character); stored as a JSON array; no audio or transcript content
  • onboarding_complete — first-run flag

4.3 Transcript file format

Each Scribe or Transcribe output is a single Markdown file named <ISO-timestamp>_<model-id>.md. The file contains timestamped transcription segments. For dual-source recordings, speaker lines are prefixed with out: and microphone lines with in:.

4.4 Dictate log format

dictate.jsonl appends one record per successful dictation:

{"date": "2026-05-04", "time": "14:23:01", "text": "the transcribed text"}

Empty transcriptions are not logged. The file is never sent anywhere.

4.5 Atomic writes

Config updates use an atomic write pattern (write to a temp file, then rename to the final path). This prevents config corruption if the process is killed mid-write. Transcript files are verified non-empty before WAV files are deleted.

5. Third-party dependencies

All libraries run in-process with no network communication of their own.

LibraryVersionPurposeNetwork access
whisper-rs0.13Whisper model inference (wraps whisper.cpp)None
cpal0.15Cross-platform audio captureNone
reqwest0.12HTTP download (model) and update metadata fetchhuggingface.co during model download; api.github.com when user manually checks for updates
hound3.5WAV file read/writeNone
symphonia0.5Decode MP3, M4A, FLAC for TranscribeNone
tauri2App framework (Rust + OS WebView)None at runtime
enigo0.6Keyboard simulation for Dictate pasteNone
serde + serde_json1JSON serialisationNone
tokio1Async runtimeNone
chrono0.4Timestamp formattingNone
uuid1Session ID generationNone

No analytics SDKs, advertising SDKs, or crash reporting libraries are included.

6. AI model provenance

Whisper transcription models

OpenAI Whisper weights converted to ggml format, distributed via Hugging Face (huggingface.co/ggml-org/). They are:

  • Publicly available and widely audited
  • Static inference artifacts — they do not update themselves or make network calls
  • Stored as local binary files; they do not execute with elevated privileges
  • Run inside the app process via whisper.cpp (via the whisper-rs wrapper)

The model files do not contain user data. They are model weights produced by training on a public speech dataset.

Silero VAD model

The optional Voice Activity Detection model (ggml-silero-v6.2.0.bin) is distributed via huggingface.co/ggml-org/whisper-vad. It is:

  • A ggml-format version of Silero VAD, an open-source voice activity detector
  • Used by whisper.cpp to skip silence between speech segments, improving transcription speed and accuracy
  • ~2 MB; downloaded only if the user clicks "Install" in Settings → Models
  • Loaded and run entirely in-process alongside the Whisper model; makes no network calls
  • Optional — if not downloaded, transcription runs without VAD (silence is not filtered)

7. No automatic update mechanism

The application has no automatic update mechanism. It does not:

  • Check for new versions on launch or in the background
  • Download or execute update payloads automatically
  • Schedule background processes for updates

Users can manually check for updates via Settings → Help → "Check for updates". This button makes a single HTTP GET request to api.github.com to fetch the latest release metadata. If a newer version is available, the app shows a banner with release notes and a button to open the download page in the user's browser. No binary is downloaded or installed by the app itself.

8. Process isolation and sandboxing

ScribeFloat is a Tauri v2 application. The frontend (HTML/JS) runs in the OS WebView with a strict CSP. All sensitive operations (file I/O, audio, IPC, OS permissions) are handled exclusively in the Rust backend. The WebView cannot make file system calls or spawn processes.

The Tauri capability model (src-tauri/capabilities/default.json) restricts which IPC actions each window can invoke. The declared capabilities are:

core:default
core:window:allow-close
core:window:allow-hide
opener:default
dialog:default
clipboard-manager:allow-write-text

No capability grants filesystem read/write access directly to the WebView — all file operations go through validated Rust command handlers.

9. Compliance notes

GDPR

ScribeFloat does not transmit personal data to any server. There is no controller-processor relationship with any third party for user data. All data is user-controlled and stored locally. If an organisation deploys ScribeFloat to process personal data in audio (e.g. meeting transcriptions containing names), the data-controller obligations rest with the organisation, not with the application vendor — the application itself never receives or processes that data centrally.

HIPAA

Audio and transcripts remain local to the endpoint. The application imposes no access controls, encryption at rest, or audit logging beyond what the OS provides. Organisations transcribing protected health information (PHI) must ensure appropriate endpoint security controls (full-disk encryption, access control, audit logging) are in place on the device.

SOC 2

There are no cloud components. The entire audit surface is the endpoint. There is no shared infrastructure, no multi-tenancy, and no vendor-operated data store.

UK NCSC / ISO 27001

The application's local-only data processing model means it does not introduce a third-party cloud data-sharing risk. The model download from Hugging Face is the only external data dependency and involves no transmission of organisational data.

10. Full removal procedure

  1. Quit the application
  2. Uninstall using the OS uninstaller
  3. Delete the app data directory: macOS: rm -rf ~/Library/Application\ Support/com.benjamin.scribefloat-v8/ · Windows: rmdir /s "%APPDATA%\com.benjamin.scribefloat-v8"
  4. Delete the transcript save folder (default): macOS: rm -rf ~/Documents/ScribeFloat/ · Windows: rmdir /s "%USERPROFILE%\Documents\ScribeFloat"

After these steps, no application data remains on the device.

11. Contact

For security-related questions or to report a vulnerability, open an issue on the project repository.