Overdesksupport ops
How it worksSafetyPricingFAQ
Sign inStart trial
Home / Security

Security & Data Handling

Last updated: 2 September 2026

Everything below describes what the product does today, with each limit stated next to the mechanism it belongs to. If you find a claim here that Overdesk does not honour, email security@overdesk.io and we will fix the page or fix the code. If you want the detail behind any of it, the security implementation notes go a layer deeper.

1. The short version

  • A human sends every message. Nothing reaches your customer unless someone on your team has read the draft and pressed send. There is no autonomous send: no schedule, rule, or confidence score can dispatch a reply on its own.
  • Drafts are generated with your own Anthropic API key, in your Anthropic account, under your agreement with them.
  • Contact details become tokens before any prompt leaves our system, and turn back into real values in the draft your agent reads. The model does not receive your customer's email address or phone number.
  • The pseudonymisation is pattern-based, and we publish its limits (Section 3). It is not a substitute for your own judgement about what belongs in a ticket.
  • We hold no security certifications (Section 9). We say so plainly rather than blur it.

2. What leaves our system, and under whose account

DestinationWhat we sendWhose accountWhen
AnthropicConversation text, pseudonymised (Section 3). When you connect a code repository, also its file listing and the contents of the files the model chooses to open while answeringYours (your API key)Every draft, triage, report commentary, and analysis, and every question asked of Ask Overdesk
Voyage AIConversation, document, and saved-reply text for embeddings, pseudonymised with the stricter storage profile; and your search queries, which when Overdesk drafts include the customer's latest message (Section 3)Overdesk (an Overdesk-owned Voyage account, not a key you supply)Knowledge-base sync, and every search
Your helpdeskThe finished draft, written back unsent (an internal note, or an unsent draft reply if you turn that on), with the real customer details restoredYours (Help Scout, Zendesk, Intercom, or FreeScout)Every draft
Your store, billing, or licensing systemYour end customer's email address, sent as the key to look them up. What comes back, their orders, plan, invoices, or licence keys, goes into the draft prompt aboveYours (WooCommerce, Shopify, Stripe, or Freemius)Every draft, once you connect one
SlackThe reports and alerts you schedule, and the answer Ask Overdesk writes when somebody asks it a question about your queue. All three have your customers' names replaced with "(customer)", and their email addresses and phone numbers left as tokens. Ask Overdesk answers from a copy of your report that was stored with the names already replaced, so they are gone before the question is asked. A report archived before we started keeping that second copy cannot be read this way at all, and Ask Overdesk says so rather than falling back to the copy in your dashboard. Two records reach you as written, both explained in Section 3: a name that is really a mailbox or a company, because it names no person, and a name your helpdesk holds as only one or two letters, because substituting something that short would corrupt ordinary words around it. The copy kept in your Overdesk dashboard restores the names, because that copy does not leave your accountYours (your workspace)On your report schedule, when an alert fires, and whenever somebody asks
ClickUpThe reports you schedule and the alerts Overdesk raises. It is the same copy Overdesk sends to Slack, on the same terms, including both exceptions above. An answer from Ask Overdesk goes to Slack only, and never to ClickUpYours (your workspace)On your report schedule, and whenever an alert fires
GitHub / Linear / JiraThe title and description of an issue one of your team opens from a conversation, with contact details removedYours (your repository, team, or project)Only when a member of your team writes one and confirms it
NeonEverything Overdesk storesOverdeskContinuously
Fly.ioApplication hosting; your data in transitOverdeskContinuously
Stripe, as our own accountYour billing details for your Overdesk subscription. We never see or store card numbers. This is separate from a Stripe account you may connect above, which is yours and which we only readOverdeskOn subscribe
ResendYour team's email addresses, for login links and notificationsOverdeskOn send

One thing happens in your browser rather than on our servers: choosing which Google documents to index opens Google's own file picker, which means your browser loads a script from Google and Google sees the request. It runs only when somebody on your team opens that picker, it is the only third-party script the product loads, and none of your support content passes through it.

That is every party that receives your data. Overdesk also *reads* from the places you connect as knowledge: your public documentation or forum, and your Notion, Google Docs, GitHub, Jira, or Linear. Those are outbound requests to systems you nominated, made with the access you granted, and they carry none of your customers' data. The product runs no analytics, advertising, or third-party tracking.

Three of the systems you connect run under an Overdesk-owned credential rather than under one of yours, and we would rather say so than have you find out. Semantic-search embeddings run under an Overdesk-owned Voyage account: Overdesk provides them for every workspace and does not ask you to supply a Voyage key. The Google Docs connection is authorised through Overdesk's own Google application, so Google records that Overdesk opened the file, though the access is the one you granted and reaches only the documents you picked. And the Slack app your team installs is Overdesk's Slack application, so what it can do in your workspace is what you approved at install. Every other system you connect, including every language-model request, runs under your own account and your own key.

The four rows above that name Overdesk are our own infrastructure and suppliers rather than anything you connect: the database, the hosting, the payment processor for your Overdesk subscription, and the service that sends your team's login emails.

3. Pseudonymisation: what it catches, and what it misses

Before a prompt reaches a language model, Overdesk runs the conversation text through a pattern-based pseudonymiser. Matches become deterministic tokens, and when the model replies the tokens turn back into the real values, so your agent reads a usable draft and the model never received the raw details. (The token format is in the implementation notes.)

Tokenised before the model sees them:

  • Email addresses
  • Phone numbers
  • Payment-card numbers (checksum-validated), IBANs, and cryptocurrency addresses
  • Social-security numbers, but only where the nearby text actually says "SSN" or "social security", since a bare nine-digit run is far more often an order number
  • MAC addresses
  • PO boxes, and street addresses introduced by an explicit lead-in ("lives at …", "address: …")
  • The name of everyone on the customer's side of the conversation, when Overdesk is drafting a reply: the person who opened the ticket, and anyone else who wrote one of the messages sent with it, such as a colleague copied in or a second contact at the same company. Taken from your helpdesk's structured fields rather than guessed from the prose, so a name it holds only as one or two letters is left as written. So is a name that is really a mailbox or a company. When a message arrives from an address like support@ or billing@, most help desks file the contact under that word, and a company record often ends in one of the usual forms. Those words are left readable, because replacing them would take the same words out of your own help articles in the same prompt, and because a mailbox names no person. A name with an ordinary word anywhere in it is masked in full, exactly as before

Four kinds of weak identifier are deliberately left intact on the way to the model: URLs, IP addresses, postcodes, and street addresses with no lead-in. Each one's pattern collides with ordinary support text (a version number, a ticket number, a plain English word), so redacting it reliably would corrupt the very ticket the model has to read; the implementation notes show the collisions case by case. The consequence, said plainly: a password-reset or invite link pasted into a ticket reaches the model intact. The same four are left intact in the copy we store and embed, for the same reason: a stored article is quoted back to the model as the source of its answer, so a version number lost to an IP pattern is an answer lost, and a link lost to a URL pattern is a citation the reply cannot point at. A credential carried inside a link is a separate matter, and it is replaced on both paths whenever it is long enough for the API-key and licence-key patterns to claim it: a long random run, a UUID, a signed-URL signature. Short link ids, and tokens broken up by dashes or dots, are not long enough for those patterns and are retained with the link; a query parameter that names itself a credential (?token=, ?key=, ?secret=) is replaced when its value mixes letters and digits, but one named nothing in particular is not. Treat a reset or invite link pasted into a ticket as retained.

The knowledge base is redacted before it is written. When Overdesk indexes a conversation, its subject, body, and resolution pass through the pseudonymiser on a slightly stricter profile than the model gets: every pattern above, plus two shapes the model path deliberately declines because in a live ticket they are more often order numbers: a card-length digit run that fails the card checksum, and a phone-length digit run written with no separators. The customer's email address is replaced with a deterministic stand-in, the same one each time, so the record still groups by customer without holding the real address.

Two limits on that. The structured name substitution does not run at rest, because it needs the contact field from a live draft; so in the indexed copy a name written into the ticket text, the requester's included, stays as written. And this covers the knowledge base, not every row in our database: two stores hold real details on purpose, the draft written back to your helpdesk (your teammate has to read a usable reply) and the raw webhook event (which sits in the job queue until it is processed and cleaned up). Both age out under Section 6, and neither is what reaches the model.

Your saved replies are indexed the same way. The templates and macros you keep in your help desk are pseudonymised on this stricter profile and indexed alongside your other content, so Overdesk can find the right one. That means their text is embedded through the Voyage account named in Section 2, exactly as your documentation and past conversations already are. These are wording your team wrote rather than a customer's message, so there is usually nothing personal in them; the redaction runs anyway, because a template written from a real ticket can carry a real detail.

Searching your knowledge base sends a search query out too. To find the right article, Overdesk searches on the ticket's subject plus the first part of the customer's latest message, so that text reaches the Voyage account above. It is pseudonymised on the same stricter profile as the knowledge base, with one difference: the structured name substitution described above needs a live contact field, so it does not run on a search query. This happens while the ticket is still open, not only after it closes.

Our own search log keeps the subject line only. The part taken from the customer's message is used to run the search and is not stored, so it is not sitting in a table here waiting to age out. What is kept is the subject, the number of results, and how the search ran, for 90 days (Section 6).

The limit that matters most: names of other people written in free text are not detected. Overdesk runs no named-entity model. If your customer writes "my colleague Dave Harrison can't log in either", that name reaches the model. The name of anyone on your customer's side who wrote one of the messages is masked, because your helpdesk hands each of those to us as a field; a name mentioned in passing has no field to read and no pattern to match. That masking is not particular to drafts. Every use of a model that reads the messages on a ticket registers the same names, so a colleague who signed their own message is masked when Overdesk writes a draft, when it classifies a ticket, when it nudges a customer who has gone quiet, when it fills in a new issue on a tracker you have connected, and in the summaries behind your reports and analyses. Where one of those reads only a ticket's subject and the opening snippet your help desk shows in a list, rather than the messages themselves, there is no author field to read and it sends the requester's name masked as it always did. That includes Ask Overdesk: when it answers a question about a report you already have, it reads a copy of that report stored with the names already replaced, and not the copy kept in your dashboard.

Your own team's names are not masked, and that is a decision rather than an oversight. When one of your agents writes on a ticket, whether or not the customer sees it, their name goes to the model as written. The drafting request runs on your own Anthropic account rather than ours, so this is your staff reaching a supplier you already chose. The model uses the name to follow who said what on a ticket several colleagues have answered, and it writes a worse reply without that. It is not signed off with, either: the instructions ban a name and a signature block at the end of a reply, because your help desk adds the real sender's signature when the message goes out. The one place a colleague's name can appear in the reply is when the draft says one of your agents is standing in for another, and only when the ticket already names them. Your customers' names are treated differently throughout, because your customer never chose any of this.

A connected store or billing account is a second source of the customer's name, and it is masked too. The masking above works from the contact field your helpdesk supplies. When you connect WooCommerce, Shopify, Stripe or Freemius, that system returns its own record of the customer, and the two spellings often differ: a billing contact rather than the writer, a company name, a middle initial. Overdesk registers the store's spelling as well before it builds the block, so that name is replaced on the way to the model and put back in the draft your agent reads, exactly as the helpdesk's spelling is. The other facts in that block are left readable on purpose: an order number, an amount, and the items on the order, so the model can see what they actually bought; the state each order, payment or subscription is in, which covers a refund, an unpaid invoice, a payment past due and a cancellation; a plan name and the dates it renews or ends; the day they first bought from you; how many orders they have placed and what they have spent with you; which products they are licensed for and on how many sites; and the last four characters of a licence key. A draft that quotes a tokenised order number answers nothing, which is the reason, but it means this block is an exception to the rest of this section rather than an instance of it.

4. Bring your own key

Drafting, triage, report commentary, and analysis all run on your Anthropic API key, encrypted at rest (Section 8). Your conversations are processed under your own commercial agreement with Anthropic, not proxied through an Overdesk-owned AI account and not pooled with another customer's traffic.

We do not train models on your data. There is no shared Overdesk model to train.

5. A human sends every message

Overdesk places its drafts into your helpdesk unsent. By default a draft arrives as an internal note; if your team turns on draft delivery, it arrives as an unsent draft reply in the composer instead. Neither is visible to your customer, and neither is sent by Overdesk. A person on your team reads the draft, edits it if they want, and sends it.

One limit belongs to FreeScout, and we would rather state it than let you meet it. FreeScout is self-hosted, so the version running is yours to choose. Its API and Webhooks module needs to be recent enough to recognise an unsent draft reply, and we read the vendor's own source to establish what happens when it is not: FreeScout treats a reply whose state it does not recognise as one to publish, so on an older module a draft may reach your customer unread. We state this as a possibility rather than a certainty because we have tested a current module and have not tested every older one. The module version we believe to be the minimum is named in the product, on the screen where your team would turn draft replies on.

On a current module a draft is not sent, and it is worth saying exactly why, because the mechanism is narrower than it sounds. Creating a draft does queue FreeScout's own send job; that job then finds nothing to send, because it collects only published replies and a draft is not one. That is a default in the vendor's code rather than a guard, which is one of the reasons Overdesk leaves an internal note by default and an unsent draft reply is something your team turns on deliberately.

None of this touches the internal note Overdesk leaves by default, which works on every version. On Help Scout, Zendesk, and Intercom the question does not arise.

Exactly one code path can put a reply in front of your customer, and the only thing that triggers it is a person choosing to send a draft they have read. No schedule, automation rule, or confidence threshold can reach it, because the autonomous path was never built.

Every draft is stored with the model that wrote it and the tokens it cost.

6. Retention and deletion

Content ages out automatically. Generated reports follow your plan's retention — 90 days (Trial), 90 days (Assist), 365 days (Pro), and unlimited (Scale); drafts, triage, alerts, and the redacted auto-send decision log are kept 180 days; search-query logs 90 days; your indexed knowledge base lives for the life of the workspace. The implementation notes carry the full schedule.

Erase one customer. An admin can erase a single end customer from Settings. Overdesk resolves their conversations, deletes the drafts, triage results, simulation results, and knowledge-base entries derived from them, and records that the request was honoured. Those conversation IDs go onto a suppression list, so the next sync with your helpdesk does not quietly re-import what you just erased.

Delete the workspace. The owner can delete the whole workspace from Settings. The Stripe subscription is cancelled first, then the workspace and its contents are removed immediately, with no grace period and no soft delete. Two things survive by design: the record that you accepted the terms, and the record that the deletion happened.

Two limits worth knowing. Report and alert text is prose written by a model, so a customer named inside it has no key to search on and is removed by the age-based schedule above rather than by a targeted erasure. And deleting your workspace does not remove the webhook you registered inside your own helpdesk; delete that one yourself, though once the workspace is gone anything the webhook sends is rejected.

7. Sub-processors

The full list, with each sub-processor, its purpose, the data it receives, and where it runs, is the table in the Privacy Policy. We keep a single canonical copy so the two pages cannot drift apart.

8. Infrastructure and access

  • Overdesk's application (Fly.io) and database (Neon) run in the United States. If you use Overdesk from elsewhere, your data is processed in the US.
  • All traffic is over TLS.
  • Helpdesk credentials, model API keys, and webhook signing secrets are encrypted at rest with AES-256-GCM, under a key derived per workspace and per purpose, so one workspace's ciphertext cannot be decrypted with another's key.
  • Every query against workspace data is scoped to a single workspace, and a test gate fails our build if a new query is written without that scope. The handful of deliberate exceptions are enumerated in the implementation notes.
  • Inbound webhooks are signature-verified. An unsigned or wrongly-signed event is rejected.

9. Compliance: what we can and cannot say

Overdesk holds no third-party security certifications. We are not SOC 2 audited, not ISO 27001 certified, and we do not offer a HIPAA BAA. If a certification is a hard requirement for you, we are not the right vendor yet, and we will tell you that now rather than during your review.

What is true:

  • For your customers' personal data inside your support conversations, you are the controller and Overdesk is the processor (GDPR Article 28). We process it only on your instructions, and the Article 28 obligations here (pseudonymisation, retention, deletion, erasure on request) are implemented in the product, not merely promised in a contract. If you need a separate data processing agreement, email privacy@overdesk.io.
  • Under the California CCPA/CPRA we act as a service provider for support content. We do not sell or share personal information.
  • Your rights, and your end customers' rights, and how to exercise them, are set out in the Privacy Policy.

10. Reporting a vulnerability

Email security@overdesk.io with what you found and how to reproduce it. We will acknowledge it, and we will not threaten you for reporting it.

We do not run a bug bounty: we are a small team and cannot fund one properly. Please do not test against other people's workspaces or real customer data. If you need an account to test with, ask and we will make you one.

Changelog

  • 2026-09-02: The masking of other people's names on your customer's side is no longer particular to drafts. Section 3 used to say that it covered writing a draft and not the other things Overdesk asks a model to do, which was true and was the narrower half of a promise worth keeping whole. Every use of a model that reads a ticket's messages now registers the same names: classifying a ticket, nudging a customer who has gone quiet, filling in a new issue on a tracker you have connected, and the summaries behind your reports and analyses. Nothing new is sent anywhere and no new party receives your data. The same text goes to the same model with more of it masked, and your team's own names are unchanged and still readable, for the reason Section 3 gives.

One correction in the same breath, found while checking that the sentence above was true everywhere it is made. The Slack row in Section 2 said every one of the things Overdesk posts to your workspace has your customers' names replaced with "(customer)". That holds for a report and for an alert. It did not hold for an answer Ask Overdesk writes about an archived report, because that answer was built from the copy kept in your dashboard, which has the real names in it. The code has been changed to match the promise rather than the promise quietly narrowed: a report is now archived with a second copy that has the names already replaced, and that is the only one Ask Overdesk will read. A report archived before this change has no such copy and cannot be given one, because the substitution cannot be run again after the fact, so Ask Overdesk declines to read those and says why.

  • 2026-09-02: One narrowing in Section 3, in favour of the answer your customer gets. Overdesk masks a customer's name by substituting each word of it wherever that word appears in the prompt, and the prompt carries your own help articles and past tickets as well as the ticket being answered. When a help desk had filed a contact under a mailbox word, that word was replaced throughout, so the model read your own documentation with a hole in it. Those words, and the usual company endings, are now left readable. Nothing that identifies a person stopped being masked: a name with an ordinary word anywhere in it is still masked in full, and a bare mailbox word identifies no person. There is one real cost and it is worth naming. The article a company name starts with is on that list, and it is also a syllable in Vietnamese names written without their accents, so a record spelled that way loses that one syllable while the full name and every other part of it stay masked. The same entry is the largest single improvement here, because that word appears in about half of everything a knowledge base holds. Where a customer's whole record is a mailbox word, there is then no name for us to replace, so it also reaches your own Slack or ClickUp workspace as written rather than as "(customer)".
  • 2026-09-01: FreeScout is now a supported help desk, and four systems can be connected to give a draft your customer's real account state: WooCommerce, Shopify, Stripe, and Freemius. Connecting one means your end customer's email address is sent to that system to look them up, and what comes back goes into the draft prompt. Both are now in Section 2, and Section 3 says plainly that this block is deliberately left readable, apart from the connected system's own record of the customer's name, which is masked like the rest. The four lookups have been part of the product since the middle of August and this page did not say so, which is the drift this changelog exists to catch and did not.

One further correction and one further disclosure, both in Section 3. The name masking used to work only from the ticket's requester, so anyone else on your customer's side who had written one of the messages, a colleague copied in or a second contact at the same company, reached the model under their real name; every one of those authors is masked now. And your own agents' names are not masked, which has always been true and is now explained rather than left for you to discover. Section 3 also states which of Overdesk's uses of a model this author masking covers, and that a name your helpdesk holds as only one or two letters is left as written.

Also newly written down, none of it new behaviour: the Slack row now names Ask Overdesk and alerts rather than only scheduled reports, and says that everything reaching your workspace has your customers' names replaced with "(customer)", correcting a sentence on the Privacy Policy that had this backwards and said the names were restored; opening the Google Docs picker loads a script from Google in your browser; the Google Docs connection is authorised through Overdesk's own Google application rather than one of yours, as is the Slack app your team installs; and the two Stripe rows are now labelled, since one is your own account that we read and one is ours that bills you. Section 5 states the FreeScout version question that decides whether a draft stays unsent, and explains why a current module does not send one. Two earlier changes reached this page with no entry here: on 28 August the Anthropic row began naming the repository code a connected GitHub account sends to the model, and on 29 August Section 3 began naming which credential-shaped query parameters are replaced inside a link. Retention is unchanged, and a person still sends every message.

  • 2026-08-07: Follow-up nudges now respect your draft delivery setting. A nudge is the short message Overdesk drafts when a customer has gone quiet on an open ticket. Until now it was always placed as an internal note, even for teams who had chosen to receive drafts as unsent draft replies in the composer; it now arrives in whichever shape you picked, the same as every other draft. Nothing about sending changed: both shapes are invisible to your customer, neither is sent by Overdesk, and a person on your team still sends every message. No new party receives your data and retention is unchanged.
  • 2026-08-07: Saved replies are now indexed like the rest of your knowledge base, so Overdesk can actually find the right template. Their text is embedded through the Voyage account named in Section 2, which it was not before, and it is pseudonymised on the same stricter profile as everything else stored. Sections 2 and 3 now say so. No new party receives your data, retention is unchanged, and nothing about how a draft is delivered or sent has changed.
  • 2026-08-06: Disclosed more about search queries. To find the right article, Overdesk now searches on the ticket's subject plus the first part of the customer's latest message, where it used to search on the subject alone. That means more of a customer's own words reach the Voyage account named in Section 2, on an open ticket rather than only a closed one. Sections 2 and 3 now say so, including the one gap: the structured name substitution needs a live contact field, so it does not run on a search query. Our own search log keeps the subject line only, so the extra text is used for the search and not stored here. No new party receives your data, and the search log's 90-day retention is unchanged.
  • 2026-08-05: Corrected where a draft is placed. This page said drafts always arrive as internal notes; since the release that added draft delivery, a team can choose to receive them as unsent draft replies in the composer instead. Section 5 and the sub-processor table now describe both. The claim that a person sends every message is unchanged, and no send behaviour changed: neither shape is visible to your customer, and neither is sent by Overdesk.
  • 2026-07-16: Restructured for length. Implementation detail (token format, redaction-collision cases, the full retention schedule, cookie and query-scoping specifics) moved to the security implementation notes. Every claim and stated limit is unchanged.
  • 2026-07-14: First published, alongside the release that shipped the pseudonymisation, retention, deletion, and erasure behaviour described here.
Overdesksupport ops · est. on a real queue
SafetyPricingvs Help Scout AIvs eeselSecurityPrivacyTermshello@overdesk.io
© 2026 Overdesk