Aldernote

Security

What the code does to keep your meetings yours. This page describes the shipped behavior, not aspirations; the honest gaps are listed at the end.

Access

  • Sign-in is Google only, and only for email addresses on the deployment’s allowlist. With an empty allowlist the app refuses every sign-in rather than opening up.
  • Sessions are stored server-side. Account pages, private reads and writes, and server actions check the signed-in account. A public share page instead requires a valid secret bearer link created by the owner; it exposes current notes and an optional transcript, never audio.
  • Connected apps reach a separate read-only endpoint with short-lived bearer tokens that Aldernote itself issues after you approve the app while signed in (OAuth 2.1 with PKCE; an app secret only if the app registers with one). Tokens for Aldernote’s own native app are issued per device and work only on the app’s separate endpoint, which reads and writes only the approving account’s data; connector tokens do not work there, and app tokens do not work on the connector. Tokens, approval codes and app secrets are stored only as SHA-256 fingerprints, a code works once, a refresh token is replaced every time it is used and revoked if reused, and disconnecting an app or a device in Settings cuts it off on its next request. Neither endpoint reads a session cookie, and the connector endpoint never serves audio.
  • Automatic Slack delivery posts to Slack’s webhook service, at an address that must match Slack’s exact webhook shape before it is stored; nothing else you type is ever fetched or posted to. The address is stored encrypted under a key derived from the server’s own secret, is shown back only as its team and app ids, and is deleted when you disconnect. Each post has a ten-second timeout and a bounded number of retries.
  • Interactive Slack chat verifies the raw request signature and rejects requests older than five minutes. It accepts only the configured app and workspace, links Slack identities with short-lived single-use codes, and scopes all reads to the linked Aldernote account. Replies go only to Slack’s fixed chat.postMessage endpoint. Conversation leases and event deduplication bound duplicate work; daily chat and search limits apply before model calls. Disconnecting removes queued work and conversation history through database cascades.

Audio

  • Recordings are stored in a private store with no public links. The browser uploads directly to storage using a short-lived token that the server mints only for the signed-in user’s own meeting and only inside that user’s namespace.
  • Every upload writes its own object, and tokens never allow overwriting one, so audio the server accepted cannot be replaced by a later or delayed upload. The server accepts one upload per recording and per part; any other upload is deleted, and a daily scan of each account’s audio storage removes objects no meeting uses.
  • Playback goes through a route that verifies your session, serves at most one byte range of about a megabyte per request, and enforces a per-account daily transfer budget, so a stuck tab cannot drain the storage allowance.
  • Long recordings are split in your browser into about-fifteen-minute parts; each part is its own job with its own bounded retry budget, and the parts are deleted once the transcript exists.

Models

  • Every model call goes through Vercel’s AI Gateway with the deployment’s own credentials; your browser never holds a model key.
  • Your notes, transcript, vocabulary and templates are quoted into prompts as data. Fences and explicit instructions reduce the risk of treating that text as instructions; they do not guarantee model behavior. The notes prompt instructs the model to use only facts from your notes and transcript.
  • Paid work starts only after an explicit claim: one guarded database statement per job, so two tabs, a retried request and the scheduled worker cannot start the same job at once. A job whose worker dies is retried under a bounded attempt budget, so a provider may occasionally process the same audio twice; you are never asked to do anything about it.
  • Daily allowances cap chat, rewrites, retries, uploads and search indexing per account, and transcription across all accounts.

Deletion

Deleting a meeting removes its database rows and its audio, and keeps a record of its storage location so that repeat scans delete uploads that finish after the meeting is gone. Deleting an account atomically removes its live data and records the audio namespace for cleanup. Access ends at that commit. Housekeeping deletes bounded batches, retries failures, and repeats scans to catch late uploads. A minimal cleanup record survives account removal; backup and provider retention are separate from this live-data process.

What is not in place yet

  • No third-party audit or penetration test. The code has been reviewed by independent adversarial model reviews, not by a firm.
  • No bug bounty. If you find a problem, tell the operator directly.
  • The Gateway’s zero-data-retention option is not enabled.
  • Bulk audio export is not offered yet; recordings are played back from their meeting pages.
  • The Slack webhook is encrypted with a key derived from the app’s session secret, not a separately managed key; rotating that secret makes stored webhooks unreadable until they are pasted again.