DEV Community

Cover image for The Meeting Bot Heard the Password. It Wrote It Down. Forever.
Dhruv Malaviya
Dhruv Malaviya

Posted on

The Meeting Bot Heard the Password. It Wrote It Down. Forever.

I searched our meeting transcripts for 'password' and got spoken connection strings, MFA digits, a verbatim angry customer, and a frame-captured dashboard. The sweep, the bot-free policy, the synthetic demo box, and retention as a setting.

I typed one word into our transcript search box: password. Four minutes later I closed the laptop and went for a walk.

Hit one: an API connection string read aloud during pairing ("just paste what I say"). Hit two: an MFA code, digit by digit to IT, transcribed correctly. Hit three: a customer's name and their angriest sentence of the year, verbatim, in a sales summary anyone can open. Hit four wasn't audio: a screen-shared dashboard captured frame by frame, real customer rows in 4K.

The room was never bugged. It was scheduled — recurring, 30 minutes, automatic notes.

Meetings became data. Nobody designed the data.
A transcript is a log no one engineered: nothing scrubs it, nothing scopes it, everything searches it. Retention defaults to forever because forever is what storage does when nobody decides otherwise. The vendor keeps a copy — the vendor is the one transcribing. And unlike every datastore we own, this one ingests secrets, PII, and candid opinions at conversational speed, from everyone, daily, without a schema.

Screen sharing is the same leak with better resolution: the terminal corner in a demo, the .env tab during a "quick look," the autocomplete that finished a customer's email on a projector. We'd never put those in a doc. We put them in a recording, which is a doc with witnesses.

The sweep
Export whatever your tool allows, then:

# spoken-secret shapes
grep -rniE 'password|passphrase|token|api[_-]?key|secret|mfa|verification code|connection string' \
  transcripts/ | grep -viE 'password (policy|manager|reset)'

# real humans in the room-data
while read -r c; do
  grep -rlq "$c" transcripts/ && echo "CUSTOMER IN TRANSCRIPTS: $c"
done < top-accounts.txt

# recordings + screen shares, from the calendar/admin export
jq -r '.[] | select(.recording or .screenShare)
  | "\(.date)\t\(.organizer)\t\(.title)"' meetings.json | sort | tail -30
Enter fullscreen mode Exit fullscreen mode

The customer-name grep is the one that ends careers of assumptions. Ours returned eleven accounts, including two under NDA.

What changed

  • Secrets are never spoken. Pairing shares a vault link, not a voice. Awkward for a week, then seatbelts.
  • Sensitive calls are bot-free by default — incidents, credential handling, escalations. Routine calls keep notes; the rule is classification, same as staging: real things don't live in rooms with pretend rules. The enforcement is boring:
# weekly: any flagged meeting next week still carrying a bot/recording flag?
jq -r '.[] | select(.title | test("incident|postmortem|migration|cred"; "i"))
  | select(.bot or .recording) | .title' meetings-next-7d.json
# non-empty output = fix the invite, not the culture
Enter fullscreen mode Exit fullscreen mode
  • Demos run on a demo box. Screen shares that might show data show synthetic data. Disposable Cube on Krova Cloud: redeployed fresh, seeded fake, deleted after the call:
#!/bin/bash
# demo-box.sh up|down
case "$1" in
  up)
    krova cubes create demo-box --cpu 2 --ram 4 --disk 40 --image ubuntu-24.04 \
      --user-data "$(cat seed-fake-customers.yml)"
    krova domains add demo-box --domain demo.example.com --port 8080 ;;
  down) krova cubes delete demo-box ;;   # nothing true was ever in it
esac
Enter fullscreen mode Exit fullscreen mode
#cloud-config
runcmd:
  - curl -sf https://storage.private/fake-customers.sql.gz | gunzip | sudo -u postgres psql app
  - systemctl restart app
Enter fullscreen mode Exit fullscreen mode

The demo can leak all it wants; there's nothing true in it.

  • The notes tool got treated like a datastore. Retention set to a number we chose, old exports purged on a schedule (find … -mtime +90 -delete — exports are copies too), search access reviewed, and the vendor's terms actually read for the first time since someone clicked "enable for workspace."

The honest part

  • Transcripts are genuinely good — searchable decisions, async teammates, onboarding gold. I don't want the tool gone; I want its defaults to have opinions. Burning it down moves the leak back into memory, which retains worse and searches never.
  • Small teams can't negotiate vendor terms. So minimize what enters the room: the bot can't transcribe a secret nobody says, nor capture a dashboard showing fake rows. Input control beats contract control.
  • "But the notes!" is a real loss, not resistance. The compromise that stuck: notes everywhere by default, bot-free where stakes say so, and the safe path made easier than the risky one — one-click demo box, vault links in every pairing doc.
  • This isn't the castle. Walls stay walls: no public IP by default, own kernel per Cube, scoped secrets. Transcript hygiene shrinks what conversations leak; architecture shrinks what machines leak. Both, always.

Forever is a setting
Every "forever" in your stack — transcripts, recordings, screenshots, exports, free-tier syncs — is a default nobody revisited. The scariest datastore you own is probably the one that fills itself while everyone talks.

Go type password into your transcript search. Then token. Then your biggest customer's name. Four minutes. I'll wait.

Top comments (0)