Skip to content

Security: Rahulk644/Meeting-Assitant

Security

SECURITY.md

Security and privacy

My Assistant is designed to keep dictation and meeting audio on the Mac. This document is the product privacy contract: what runs locally, what can leave the machine, what is stored, which permissions are used, and how to report a vulnerability.

Processing model

Local by default

  • Microphone and meeting-app audio capture run locally.
  • Voice activity detection and speech transcription run locally through the selected verified model by default.
  • Deterministic dictation cleanup runs inside the app.
  • Optional Smart Polish runs through the bundled local runtime only after the user separately downloads a verified Gemma model.
  • Meeting transcripts, notes, corrections, and optional recordings are stored locally.
  • There is no My Assistant account, analytics SDK, usage telemetry, advertising identifier, or automatic crash-report upload.

Agents is not part of the initial product. Production exposes only a disabled Coming soon label and does not package Agent helpers or initialize an Agent runtime.

Data that can leave the Mac

  1. Model downloads. After an explicit choice, the app downloads a revision-pinned speech or Smart Polish model from the named model host. The artifact is accepted only when its size and SHA-256 match the built-in catalog. Partial or mismatched downloads are not loaded.
  2. Optional meeting Intelligence provider. If the user selects a cloud provider for meeting notes or Ask, the requested meeting text is sent to that provider with the user's Keychain-backed API key. Audio is not sent. The local option sends nothing, but requires its separate runtime/model installation.
  3. Optional private meeting transcription. If the user explicitly selects their own private worker, bounded microphone and meeting-audio speech segments are sent to that authenticated server. The supported HTTP path is an SSH-tunnelled loopback address; other destinations require HTTPS. Capture metadata, Accessibility evidence, participant identities, stored transcripts, notes, and optional video are not sent to the worker. Private mode fails closed: a connection failure is shown to the user and never starts the installed on-device model.

Third-party cloud speech transcription, sync, public sharing, telemetry, and a My Assistant account are not implemented in the current beta.

Stored data

Runtime data lives under ~/Library/Application Support/My Assistant/:

Path Contents
models/ separately downloaded, verified speech and Smart Polish model files
data/settings.json non-secret preferences mirrored from the UI
data/meetings/*.json saved transcripts, corrections, summaries, and notes
data/meetings/rec/*.mp4 optional meeting screen recordings
data/tmp/ private short-lived request/audio files, removed immediately or at next launch

Production logs live under ~/Library/Logs/com.myassistant.desktop/. They contain lifecycle phases, model IDs, timings, and error categories—not transcript text, focused-field contents, audio, or API keys.

Dictation history is session-only and held in memory. Secure-field dictation is excluded from history, visual changes, logs, and model inference. Dictation audio is written only when the authoritative final pass needs a WAV; the file uses a unique name and private permissions and is removed immediately afterward.

The entire repository data/ tree, local app bundles, DMGs, native binaries, model files, acceptance sessions, demo renders, audio, and benchmark corpora are ignored by Git.

Secrets

Provider API keys and the private transcription bearer token are written directly to macOS Keychain. They never enter settings.json, localStorage, logs, temporary files, command-line arguments, or committed fixtures. The Rust service reads only the credential for the provider selected by the current request; the capture helper receives only the app's per-launch local token.

Custom remote providers require HTTPS. Plain HTTP is allowed only for loopback services on the same Mac. Provider responses and request bodies are bounded, and unknown provider identifiers fail closed.

Local service boundary

The packaged UI and API run inside the Tauri process on 127.0.0.1:8790. Startup fails closed if another process already owns the port. Each launch generates a random secret that is exchanged for an HttpOnly, SameSite cookie. Requests with an unexpected Host, Origin, or token are rejected.

The local transcription and Smart Polish helpers bind only to loopback, require per-launch bearer authentication, limit request sizes, and terminate when the owning app exits. An optional private transcription worker is selected and validated in Rust, requires a separate Keychain-backed bearer token, and must use HTTPS or an SSH-tunnelled loopback URL. Model paths and runtime executables are selected server-side; the WebView cannot supply an arbitrary executable path.

The optional meeting Intelligence choice is currently a separately installed LiteRT-LM process, not a bundled helper. Its verified install/update/remove, executable-integrity, port-ownership/authentication, and recovery lifecycle must be completed before it is presented as a first-class clean-install local runtime. Until then, it is an explicit advanced local setup; cloud alternatives remain BYOK and receive transcript text only.

The content-security policy denies external scripts, frames, objects, and arbitrary network origins. The packaged release payload is generated by the build, validated before the local server starts, and cannot be promoted through a URL or saved preference.

Dictation target boundary

The dictation-target helper is a short-lived native Accessibility session tied to the field focused when dictation begins. It reads only the focused app/role, non-content identity attributes, selection range, and a small prefix needed for sentence-start classification. It does not walk the Accessibility tree, capture a screenshot, write field text to disk, or use the network.

For live-capable models, the helper owns one provisional span. Before every update or final replacement it revalidates the process, control identity, exact tracked text, and cursor. If any evidence changes, it stops mutating. The app copies the final result rather than guessing at a target. Secure, code, terminal, non-editable, and selected-text targets do not receive live preview.

Model and native-code integrity

  • Speech and Smart Polish downloads use revision-pinned URLs, exact sizes, and SHA-256.
  • transcribe.cpp and llama.cpp are built from pinned commits; a changed checkout fails the build.
  • The release app, DMG, and every nested executable are signed and verified with hardened runtime.
  • The main app and microphone capture helper carry the audio-input entitlement required by hardened runtime.
  • The artifact verifier rejects ad-hoc or wrong-authority nested code, packaged model weights, Agent helpers, non-arm64 executables, and a non-production UI contract.

The independent beta uses a stable self-signed certificate. This detects accidental modification and keeps a stable local code requirement, but it is not an Apple Developer ID and cannot be notarized. Gatekeeper will therefore require Privacy & Security → Open Anyway for each distributed build. Public distribution should not claim Apple verification until Developer ID notarization and stapling are mandatory.

macOS permissions

Permission Purpose Notes
Microphone Dictation and the user's meeting audio Requested on first use
Input Monitoring Default bare Right Command shortcut outside the app Combination shortcuts use Carbon and do not require it
Accessibility Final paste, bounded live-target reconciliation, and meeting speaker/window evidence Secure fields fail closed
System Audio Recording Other meeting participants No meeting bot or virtual audio driver
Screen Recording Optional meeting video Not required for audio-only meetings

Settings shows live state only where macOS exposes a reliable query. For Microphone and System Audio it uses honest first-use guidance rather than inventing an allowed/denied result.

Recording consent

Recording laws vary. Some jurisdictions require every participant's consent. The operator is responsible for obtaining required consent and complying with organizational policies.

Reporting a vulnerability

Do not open a public issue containing a vulnerability, transcript, API key, model token, or other private data. Use GitHub's private vulnerability-reporting channel when enabled, or contact the maintainer through a private repository channel. Include the affected version, macOS version, reproduction steps, impact, and the minimum redacted evidence necessary to investigate.

Supported security fixes target the current beta branch. There is no paid response SLA, but credible reports should be acknowledged and triaged before public disclosure.

There aren't any published security advisories