Security
What stops it breaking your product?
Four things, and none of them is the model behaving well. Reads and writes are separate, and anything that changes data stops to show your user a confirmation card with the real values on it. The assistant can only call tools you declared in your own repository, so it has no capability you did not write down. It runs as the signed-in user, never as an administrator, so your API makes the same authorisation decision it always did. And every call is logged with what actually ran and what came back.
What it promises
It doesn’t touch money.
No checkout, no payments, no card data. Not a setting you switch off. It is simply not something Verb does, and it never will be.
Nothing changes without a yes.
Anything that edits or deletes shows your user exactly what is about to happen, in plain language, with the real details. They confirm, or it does not happen.
It never claims work it didn’t do.
When something fails, it says so. Your user gets an honest “that didn’t work” instead of a confident lie, and you hear about it before they do.
Every action has a real name on it.
A complete log of what was done, who asked for it, when, and whether it actually worked. It names the person, never “the AI agent did this”, so “what happened to this account?” is one search away.
Everything below names a mechanism rather than a promise, so you can check it against the product rather than take our word for it.
Here with a security checklist? Skip to what is in place.
Reads and writes are separate, and only reads run unattended
Every tool you declare is classified read, write or destructive. Reads execute. Anything that changes data stops and shows the person a card naming the actual action and the actual values, “cancel order 1041” rather than “confirm action?”, and nothing happens until they click it. A declined card is not retried.
It can only do what you wrote down
Capabilities come from a verb.md file in your repository, reviewed in a diff like any other code. There is no general internet access, no database connection and no way for the assistant to reach past that list. A tool you never described does not exist as far as it is concerned, however the question is phrased.
It acts as the user, never as an administrator
Tools run in that user's browser against your API with the credential they already hold. Verb is never given a wider key of its own, so your existing authorisation is the authorisation. An anonymous visitor is read-only by default and every write is refused until your backend vouches for who is asking.
It only answers on domains you have proven you own
A site key is public: it ships in your page source. So the check that matters is the origin one. It answers only on verified domains, and a request from anywhere else is refused before a model is called, which is what makes a copied script tag worthless.
Tool results are data, not instructions
Everything returned by your API is fenced and declared untrusted to the model, so content that reads like a command is reported rather than obeyed. And because a write still stops at a confirmation card a human has to click, a successful injection still cannot finish a destructive action by itself.
Every call is on the record
Who asked, which tool ran, the arguments it ran with, what came back, and whether the result was verified rather than merely claimed. That log is yours, in your dashboard, alongside the conversations themselves. An action reported as done that did not happen is the one outcome the whole design exists to prevent.
A test site that stays on your computer
Every site has a test site whose key only answers on localhost. It runs your actions for real against your development app, so you watch the assistant use your actual API before your users can reach it, and anything that changes data still asks first.
Tenants are separated in the database, not just in queries
Conversation data sits behind Postgres row-level security, so a query that forgets its tenant returns nothing rather than returning somebody else's rows. The failure mode is deliberately the visible one.
In place today
Every control below is running in production right now, with what it means and how it works.
Encryption in transit
In placeNobody sitting between your user, your product and Verb can read what goes past.
TLS on every hostname, with plain HTTP redirected rather than served. The database listens only on the loopback interface, so queries never cross a network at all.
Browser security headers
In placeThe instructions a browser enforces on our behalf: forbid framing, refuse to guess at content types, never fall back to plain HTTP, and refuse to load or talk to any origin not on a fixed list.
A full set on all three hostnames, including a content security policy, HSTS for two years across every subdomain, and a permissions policy that switches off camera, microphone, geolocation and payment at the browser. Run any public scanner against askverb.com and app.askverb.com and you can grade this yourself in ten seconds, which is the point of it.
Account security
In placeHow somebody proves they are allowed into the dashboard, and what a breach elsewhere would cost you here.
There are no passwords at all, which is the strong version rather than the missing one: no hash to leak, no credential reused from a site that was breached, and no reset flow to attack. Sign-in is Google, GitHub, or a six-digit code that expires in ten minutes and dies after three wrong attempts. Linking a second provider requires that provider to assert the address is verified, so signing up elsewhere with your email does not reach your account.
Tenant isolation
In placeOne customer's data cannot come back in another customer's response, even through a bug.
Postgres row-level security, forced, which applies to the table owner too rather than only to unprivileged roles. A query that forgets which site it is for returns nothing instead of returning somebody else's rows, so the failure mode is deliberately the visible one. The orchestrator also refuses to start if that is ever switched off, because tenant isolation silently turning itself off is the one fault nobody would notice in time.
Audit log
In placeA record complete enough to answer “what did this thing do to my account” months after it happened.
Who asked, which tool ran, the arguments it ran with, what came back, whether the result was verified rather than merely claimed, and if an action did not happen, which of the reasons it was. It is in your dashboard, and it is yours.
Retention and deletion
In placeData is kept until you ask for it to be deleted, and then it is actually deleted, rather than hidden from a view.
Conversations are kept, so the record of what happened stays answerable, and you can export them as CSV or JSON at any time. To delete one user's data, send us the user ID your backend puts in their token; to delete everything, close the account. Deleted rows leave the live database at once, and the nightly backups that still hold them are gone within 14 days.
Backups, and restores that are tested
In placeYou can get the data back after a mistake or a failure, and somebody has proved it rather than assumed it.
A dump every night, then a separate job that restores it into a scratch database, counts the rows against production and fails loudly if they disagree. That runs weekly, because a backup nobody has restored is a belief.
Vulnerability disclosure
In placeA published route for a researcher to report a hole to you instead of to everybody at once.
A security.txt at /.well-known/security.txt, pointing at the person who wrote the code, with a reply within 72 hours.
Private user identity
In placeYour users cannot be tracked from one product to another through Verb.
Identity arrives as a token your backend mints, and is hashed with a salt unique to your site and never stored. So the same person using two Verb-powered products cannot be linked between them, by anyone, including Verb. To have one user's data deleted, send us the user ID your backend puts in their token and we delete it.
Common questions
What stops the AI from deleting my production data?
Every tool is classified as read, write or destructive, and only reads run on their own. Anything that changes data stops and shows the user a confirmation card naming the exact action and its real arguments, and nothing runs until they click it. The assistant also cannot invent a capability: it can only call tools you have written into your own verb.md file, so an action you never described does not exist for it.
Can the AI assistant see data the user is not allowed to see?
No. Tools run in the user's own browser against your own API, carrying whatever credential that user already has. Verb never holds a second, wider key, so your API makes exactly the same authorisation decision it makes for every other request from that person. If they cannot see it without Verb, they cannot see it with Verb.
What happens if someone copies our script tag onto another site?
Nothing works. A site key only answers on domains you have verified, and requests from any other origin are refused before a model is ever called. The key is public by construction, because it ships in your page source, which is precisely why the domain check is what actually holds.
Can a prompt injection make the assistant run a destructive tool?
Tool results are fenced and declared to the model as untrusted data rather than instructions, so text arriving from your API that reads like a command is reported rather than followed. The stronger guarantee is structural: a write still stops at the confirmation card, which a human reads and clicks, so a successful injection still cannot complete a destructive action on its own.
Do you train models on our data?
No. Your data is not used to train anything, by us or by the model provider on our behalf. Conversations belong to your users and are visible to you in your dashboard, and Verb's internal staff view deliberately does not show them.
Can we test it before our users see it?
Every site comes with a test site alongside it: its own key, its own log, and a Test badge on the widget. Its key only answers on localhost, so it runs inside your app on your own computer, against your development data, and never reaches your users. Anything that changes data still asks for a yes first.
Found something here that does not hold, or holding a security questionnaire you need filled in? Write to vishnu.ps@askverb.com and you will reach the person who built it.