🎉 NoteMeeting đã có trên Chrome Web Store Add to Chrome →
Security & data flow

How your meeting data is handled

Last updated: May 16, 2026  ·  Owner: [email protected]

The short, honest version. Your meeting audio goes from your browser straight to Soniox over an encrypted WebSocket. It never touches our server. Transcripts live on your device. When you ask for an AI recap, your transcript text is forwarded once to Groq, used to generate the summary, and not stored. The only thing we keep in our database is what we need to bill you and enforce your plan: license key, plan, minutes used, email from Polar, a device ID.

1. What this page is — and what it isn't

This page describes what actually happens to your data, today, in the running system. It's written by the founder, not by a compliance team.

NoteMeeting is operated by a single person. We do not currently hold SOC 2, ISO 27001, or HIPAA attestations, and we don't claim to. We don't run an annual third-party penetration test. We don't have a 24/7 SOC. If those controls are hard requirements for your organization, NoteMeeting is probably not the right fit yet — and that's fair feedback we'd want to hear at [email protected].

What we can commit to is that the data flow described below matches the source code, and that we'll update this page when the architecture changes.

2. The full data flow, in one diagram

┌────────────────────────────────────────────────────────────────────────┐ │ YOUR BROWSER (Chrome extension or notemeeting.com) │ └────────────────────────────────────────────────────────────────────────┘ │ │ 1. Capture tab audio locally (chrome.tabCapture) │ ├─── HTTPS ───▶ notemeeting.com server │ "give me a temporary Soniox key for this session"(server returns a key that expires in ≤ 1 hour) │ └─── WSS (encrypted WebSocket) ───▶ api.soniox.com audio chunks flow directly, browser ↔ Soniox our server never sees the audio bytes ◀── transcript text streams back to browser ┌────────────────────────────────────────────────────────────────────────┐ │ ON YOUR DEVICE │ └────────────────────────────────────────────────────────────────────────┘ transcript persisted in chrome.storage.local (extension) or in your notemeeting.com account view audio bytes discarded — never written to disk by us ┌────────────────────────────────────────────────────────────────────────┐ │ WHEN YOU CLICK "RECAP" OR ASK THE COPILOT │ └────────────────────────────────────────────────────────────────────────┘ transcript text ─── HTTPS ──▶ notemeeting.com server │ └─── HTTPS ──▶ api.groq.com (Llama 3.3 70B) ◀── summary text streams back not written to our DB ┌────────────────────────────────────────────────────────────────────────┐ │ WHAT WE STORE IN OUR DB (Supabase Postgres) │ └────────────────────────────────────────────────────────────────────────┘ licenses : license_key, plan, status, expires_at, email quotas : audio_minutes_used, meetings_count, recaps_used, translator_minutes_used device binding : a pseudonymous device_id (license ↔ device pairing) we do NOT store: audio, transcripts, recap text, copilot Q&A, meeting titles, participant names, calendar metadata

3. Where audio actually goes

The Chrome extension captures the audio of the meeting tab using the browser's chrome.tabCapture API. That audio stream is opened as a WebSocket directly to api.soniox.com. The connection is TLS-encrypted (WSS).

To open that connection, the extension first calls a small endpoint on our server which issues a temporary, session-scoped API key from Soniox. The temporary key has a TTL of one hour and is bound to that single browser session. Our server returns the key and forgets it; we don't log it.

The audio bytes themselves never transit our server. They flow browser → Soniox. We could not produce a copy of your meeting audio if we tried, because we don't have it.

Soniox processes the audio in real time and streams the transcript text back to the browser. You can read Soniox's own security and privacy stance at soniox.com/privacy.

4. Where transcripts live

Chrome extension. Transcripts are written to chrome.storage.local on your device. They are not synced to any cloud by us. They are visible only to the Chrome profile that captured them.

notemeeting.com dashboard. If you choose to view your meeting list on the web app, your transcripts are sent from the extension to your account view and rendered in the browser. We expose them under your authenticated session only.

Server-side persistence. Transcript content is not written to our Postgres database. We store that a meeting happened (a row counting minutes used), but not what was said.

5. What happens when you ask for a recap or use the Copilot

Recap and the in-meeting Copilot are the only points where transcript text touches our server. The flow is:

  1. The extension POSTs your transcript text to /api/recap (or /api/recap-chat for follow-up questions).
  2. The server checks your license + remaining quota.
  3. The server builds the prompt and calls api.groq.com with the Llama 3.3 70B model.
  4. Groq returns the summary text. The server forwards it to your browser.
  5. The server does not INSERT the transcript, the prompt, or the response into any table. After the HTTP response finishes, the strings are out of scope for garbage collection.

The translation feature (Voice Translator) follows the same pattern: short text segments are forwarded to Groq, the translation is returned, nothing is persisted.

One nuance worth being explicit about. Groq is a third-party inference provider. We rely on their commitments — see groq.com/privacy-policy — that prompts are not used to train models. If you have a regulated workload where third-party inference is a non-starter, please don't use the recap/Copilot features.

6. What's in our database, exactly

Our database is Supabase Postgres (managed Postgres on AWS, encrypted at rest with AES-256). The schema, simplified, is:

Table What it holds Why
licenses license_key, plan, status, expires_at, email (from Polar checkout) Bill you, deliver your key, enforce expiry
quotas audio_minutes_used, meetings_count, recaps_used, translator_minutes_used (counts only) Enforce plan limits per billing cycle
device_bindings A hashed/pseudonymous device_id paired with license_key Prevent one license being shared across many machines

That's the whole list of tables that hold user-linked data. There is no transcripts table, no recaps table, no meetings_content table.

7. Encryption

  • In transit: TLS 1.2+ for all HTTPS, WSS for the Soniox stream. HSTS is enabled at the application layer via Helmet.
  • At rest: The Postgres volume is encrypted at rest by Supabase / AWS (AES-256). Daily automated backups inherit the same encryption.
  • Secrets: Provider API keys (Soniox, Groq, Polar, Resend) are stored as encrypted columns in a separate api_keys table and decrypted in process memory only at call time. They are never logged.

8. Who can access the data

A single administrator — the founder — has production access. There is no engineering team, no contractor with database access, no shared admin login. The trade-off is small blast radius and a clear audit trail, at the cost of bus-factor: if the founder is unreachable, support requests will wait.

Access is via SSH key authentication to the VPS (password login disabled, root login disabled, fail2ban on port 22) and an authenticated Supabase dashboard session. There is no shared admin panel exposed to the public internet.

9. Third-party processors

Every external service we route data through is listed here. If a vendor is not on this list, we are not sending data to it.

VendorWhat it seesRegionTheir policy
Soniox Raw audio of the meeting (real-time, in-flight) US soniox.com/privacy
Groq Transcript text for recap, Copilot questions, translation US groq.com/privacy-policy
Supabase License records, quota counters, device IDs AWS (Southeast Asia) supabase.com/privacy
Polar Your email, payment method, subscription state US / EU polar.sh/legal/privacy
Resend Your email address + transactional email content (license delivery, renewal notices) US resend.com/legal/privacy-policy

10. Retention & deletion

  • Audio: Never stored by us. Soniox states audio is not retained after the streaming session ends.
  • Transcripts on your device: Persist until you clear them. You control them.
  • Transcript text on our server: Discarded as soon as the recap/Copilot response returns (single request lifetime).
  • License + quota records: Kept while your subscription is active, plus 90 days after cancellation for billing dispute purposes.
  • Usage counters: Deleted 12 months after your subscription ends.
  • Server logs: Application logs are rotated at 14 days. We do not log request bodies, transcript content, or API keys. We log IP, path, status, and timing for abuse-prevention purposes.
  • Email request: You can request full deletion of your record at any time at [email protected]. We complete the deletion within 14 business days.

11. Application-level controls

  • Helmet sets a strict Content-Security-Policy that allows connections only to api.soniox.com, api.groq.com, and our own origin.
  • Rate limiting is in place on login, license validation, recap, Copilot chat, translation, checkout, and meeting actions. Bursts are throttled per IP.
  • Session secret is required as an environment variable at boot; the server refuses to start in production without it.
  • License keys are validated against Supabase on every quota-bearing call, not just at activation.

12. Reporting a vulnerability

If you've found a security issue, please email [email protected] with as much detail as you can share (repro steps, affected endpoint, impact). We aim to acknowledge within 48 hours and to keep you informed through the fix. We don't run a paid bounty program yet, but we'll publicly credit you in this page if you'd like.

Please avoid automated scanning that generates load (we'll see it on rate-limit dashboards and may temporarily block your IP). Manual testing on your own account is welcome.

13. What changes will be reflected here

This page is the source of truth for the data flow. When we change a provider, add a new persistent store, or extend what's logged, this page is updated and the "Last updated" date at the top moves. Material changes are also called out in our release notes.

Questions: [email protected].