Security
What we found, and what we fixed.
People bring this product decisions they can’t take anywhere else. We think the honest way to earn that is to publish what a review actually turned up — not a badge. Below is the full result of the most recent one, including the limits we haven’t closed.
What was reviewed
- Every server endpoint: the counsel and voice APIs, the public sample endpoint, and the machine-facing API other companies' agents call
- Database access rules on every table, plus the exact column-level write permissions each signed-in account holds
- All payment handling: checkout, the billing portal, and the Stripe webhook that grants plans
- The browser app: HTML-injection paths, credential handling, and what the shipped bundle contains
- Dependency advisories and HTTP response headers
What was found and fixed
Every item below was corrected in the release that ships with this page. None of them exposed one customer’s conversations to another — the account isolation described further down held throughout. Most were ways the product’s own usage limits could be sidestepped.
- Usage limits could be reset by the account holder. A signed-in account could write directly to its own profile record and zero out its daily message limit, its free-tier counter and its weekly voice-call allowance. Write access is now restricted at the database layer to the two fields the app actually changes; everything else is server-only. This never exposed anyone else's data, and it could not be used to grant a paid plan.
- The daily limit could be outrun by simultaneous requests. The limit was checked before a request and recorded after it finished, so requests sent at the same moment all passed the same check. Checking and recording now happen as a single indivisible database operation.
- Promo codes could be guessed. Redemption had no cap on failed attempts. Attempts are now limited per account per hour, and every attempt is recorded.
- The app shipped without security response headers. Clickjacking, MIME-sniffing and referrer protections, strict transport security, a permissions policy restricting device access, and a Content Security Policy are now set on every response.
- Voice credentials were issued for any agent the browser named. The endpoints that mint voice-session credentials accepted any agent identifier sent by the client. They now issue credentials only for this app's own voice agent.
- A plan could activate before payment settled. With slower payment methods a checkout can complete before the money clears. The subscription tier is now granted only once payment is confirmed.
- Two endpoints had no usage ceiling. Conversation titling is now capped at one generation per conversation, and in-app feedback reports are capped in both size and frequency.
- The machine-facing API could be probed for valid keys. Invalid API keys could be tried without limit. Failed key attempts are now capped per network address per day across every endpoint of that API.
- Checkout return links could be influenced by the calling page. The addresses customers return to after checkout are now restricted to a fixed list of our own.
- Housekeeping. Dependencies carrying published advisories were updated, build-only tooling was separated from what actually ships to your browser, and an unused component holding the app's only raw-HTML rendering path was deleted.
We publish findings rather than a pass/fail badge. Reviews happen when meaningful changes ship to sign-in, data access, payments or backend endpoints — not on a fixed calendar we can quietly miss.
What was already in place
The review confirmed these were working as intended, and they remain the controls the product rests on.
- Your conversations are isolated at the database.Row-level security is enabled on every table holding user data, and each account can read and write only its own rows. This is enforced by the database, not by the interface.
- Payment events are cryptographically verified.Every message from Stripe has its signature checked against the raw request before anything is acted on. Prices and what a purchase unlocks are resolved on our servers from our own catalogue — never from what the browser sends.
- Secrets stay on the server.The review confirmed no API key or server credential appears in the code your browser downloads, or anywhere in the project's history.
- API keys are never stored.Keys issued to companies whose agents consult the advisors are stored only as an irreversible hash. We cannot recover one; a lost key is reissued, not looked up.
- Passwords are never seen by us.Sign-in is handled by Supabase Auth. Passwords are hashed by the auth provider; we never receive or store them.
Known limits
Things we have chosen, or not yet closed. Listing them is the point of a page like this.
Reporting a problem
If you find something, tell us and we will fix it and credit you here if you’d like. Use the Send feedback option inside the app, or reach Anabasis Intelligence, who builds and operates The Prince AI. Please don’t test against other people’s accounts — if you need an account to probe, ask and we’ll set one up.
How we handle your data — what we store, what we never do, and how to delete it — is on the privacy page.