Trust and security
Uiia is an in-app assistant a product team embeds in their own web app. This page says what it stores, what it does not, what the model can and cannot do, and what we have not built yet. It describes what is running today — not what is planned.
On this deployment the assistant is currently on, and questions may reach Google (AI Studio), Groq, Cerebras, OpenRouter. Nothing else is sent anywhere.
Nothing answers your users until a person approved it
Answers come only from content your own team marked approved at the approval desk. A draft — including one the AI itself wrote — reaches nobody. That filter lives in one function that every answering path goes through, rather than in a rule several places have to remember.
What the model can and cannot do
- It holds no tools. Requests are built without any field for one. A hostile question, or a hostile sentence inside a document your team approved, can steer the words that come back; it cannot make anything happen, because there is nothing to happen.
- It cannot invent a link. It is shown a numbered list of the places you registered and answers with numbers. It never writes an address of its own, and a number that is not in the list is discarded rather than corrected.
- It reads only approved content. If nothing your team approved matches the question, the model is not asked at all — a model with nothing to read can only invent, so it is not given the chance.
- It names its sources, and when your content does not cover something it says so instead of guessing.
- It runs read-only. It cannot change your app, your data, or its own knowledge. Only a person at the approval desk can do that.
Sensitive things are removed before anything is stored
Nobody can stop a person typing a card number into a help box. What we can do is decline to keep it, say so at the moment it happens, and leave a record honest enough that you can check the promise rather than believe it.
- Detected and deleted at the door. Card numbers (checked against the real card-number checksum, so an order reference of the same length survives), email addresses, phone numbers, government id numbers, bank account numbers and API keys are removed from a question before anything else sees it — before the matcher, before any AI model, before storage.
- The person who typed it is told, in the same breath as their answer: "Someone typed a card number, so it was removed before anything was recorded."
- A receipt stays, and it holds two things — what kind of thing was removed, and when. Never the thing itself, never a fragment of it, never a hash of it (a hash of a card number is a card number to anyone holding a list of them), and never who typed it.
- You can watch it working. Every removal is listed on your own approval desk with its kind and its time, so the mechanism is visible rather than asserted.
Two honest limits. Detection favours precision: it would rather miss an exotic format than eat part of a real question, so it is a strong safety net and not a guarantee. And the times on those receipts are real times — if you keep your own web server logs, you could in principle line one up with a visit. We cannot, and we hold nothing that would let us.
Nobody is named unless they chose to be
Uiia is anonymous by default and stays that way unless a person is asked, in plain words, and says yes. Nothing is ever inferred about anybody: your team tags which of your own articles carry an offer, and the assistant simply notices that the article it answered from is one of them. It never decides that somebody sounds like a prospect.
- The answer comes first, in full. The choice sits underneath an answer already given. It never gates information, and declining costs nothing.
- Two options that look the same. Neither is the bright button. That is a rule in the stylesheet, not an intention.
- What sharing shares is written before the click — the email address, the one question that prompted it, and who receives it, by name.
- The wording is ours. A customer supplies the subject; we write the sentence around it. Some customers will want to rewrite it, and that is exactly the constraint that keeps this from becoming a lead-capture popup.
- Asked once a visit, and never again after a no. A decline lives in that person's own browser and reaches us not at all — there is no endpoint that records one, so declines cannot be counted even in principle.
- A yes produces three things and no others: an address, that one question, and a timestamp. Never a transcript, never a session, never "this person also asked".
- Knowing who somebody is is not permission. If the app already knows the visitor, that still needs the same explicit click.
A handoff travels; it does not live here. When a customer has given Uiia somewhere to send enquiries, the address, that one question and the time are posted to their own system and Uiia's copy is deleted the moment it is accepted — usually about a second after it was typed. That is deliberate rather than tidy: a message we successfully handed on and then also kept would carry their obligation and ours, for the same person, for no benefit to anybody. This deployment can do that, and does it as soon as a customer names a destination.
What is kept, and for how long. A handoff with nowhere to go — no destination set, or one that could not be reached — waits on that customer's approval desk and is deleted automatically after 90 days by a nightly job, because a retention limit nothing enforces is a claim rather than a policy. Delivery is retried on widening gaps and then stops; the record stays visible and marked undelivered rather than quietly disappearing, because losing somebody's request for help in silence is worse than any amount of noise about it.
Who to ask. Before any of that, the customer whose app you were using can delete it on request: they are the data controller and Uiia processes on their behalf, so a request to be forgotten goes to them, and they remove it here. There is deliberately no public "delete this address" door — an unverified one would let anyone erase a company's enquiries, and a verified one would mean holding more about a person rather than less.
What is stored, and what is not
| Stored | Never stored |
|---|---|
|
The help content your team wrote or approved. The map of places in your app you registered. Your guided walks. A count of questions asked per day. Questions your guide could not answer — the words, scrubbed of anything sensitive, with nobody attached (see below). A receipt for each removal: what kind, and when. Whether people found an answer useful, as a tally. Model cost per day, in fractions of a cent. A count of pointers that failed, so we can tell you which ones broke. Your credentials, as one-way hashes — including each person's own. Each person's name and role, and who approved which article. For anyone who asked to be contacted: their address, the one question, and when — until it is delivered, which deletes it. Where a customer's handoffs should be sent, encrypted at rest. A read-only GitHub token, if you connected one, encrypted at rest. |
Questions that were answered. The answers people get. Conversations — they live in the browser tab and vanish with it. Any identifier for the person asking, unless they chose to give one. Anybody who declined — including the fact that they declined. Cookies, session recordings, mouse tracking, IP-linked records. Anything from your app's own database. Any credential of yours beyond the two above. Any line of your source code. |
The one thing recorded in words, and exactly why. When somebody asks something your approved content cannot answer, the question itself is kept — because "fourteen people asked about SSO and got nothing" is the most useful sentence this product can say to your team, and no counter can say it. Nothing is attached to it: no identifier, no session, no address, no time finer than a date. Repeat phrasings collapse into one row with a count, so it is a tally rather than a log, your team can delete any of it from the approval desk, and once you write the answer the gap disappears.
A question that was answered is never written down at all, and neither is any answer. Conversations live in the browser tab and vanish with it. Nobody can read back what your users asked and got — including us.
Cost cannot run away
- A daily ceiling on model spend per customer — currently $1.00 — checked before each call against that call's worst case, so it is a ceiling rather than a line the last question of the day gets to cross.
- A daily ceiling of 500 questions per customer.
- Free-tier models are always tried before paid ones.
- Spend is recorded against the model that actually answered, and a model whose price we have not verified is never called at all.
- Reaching a limit produces an honest stop and the answer from your approved content — never a surprise charge.
Credentials
- Two kinds, deliberately different. The embed key ships in your page source and is meant to be public: it can ask questions and read the map you registered, and it can be locked to one origin. The management key is secret and is the only thing that can write content, approve it, or change the map.
- Both are stored as one-way hashes. Neither can be read back out of the system by anyone, us included; a lost key is replaced, never recovered.
- Our model provider keys live in the deployment environment only — never in the database, never in the source. There is no in-app key store for them by design.
- Two exceptions, both narrow, both yours to end. Each is held encrypted
under its own key — keys that stay in the deployment environment and never in the
database beside the thing they wrap — and neither is ever returned by any endpoint or
shown again. They cannot live in the environment the way our own keys do, because they
are yours and you must be able to change them without waiting for a release.
- Where your handoffs go. If you ask Uiia to post them to your own system, we hold that address. The desk shows the host name and the date you set it, and nothing more.
- A read-only GitHub token, if you connect a repository so Uiia can tell you which of your articles a release may have made untrue. The desk shows the repository and the date, never the token.
- And the honest part of that second one. Uiia reads your releases and the names of the files each release touched. It never calls a file-contents endpoint, so it never reads a line of your code. What it cannot claim is that the token forbids it: GitHub's narrowest useful permission is still “Contents: read”, and there is no names-only scope to ask for. So this is a promise about what our code does, which you can hold us to, rather than a claim about a permission that does not exist. Two things follow, and we would rather say them than have you find them: GitHub's comparison response carries patch text alongside the filenames, so that text passes through the request — nothing reads it, stores it or sends it on; and the strongest control here is yours, not ours, because you can revoke the token at GitHub at any moment without telling us.
- Beyond those two, Uiia holds no credential of yours for any other system and connects to nothing of yours.
One customer cannot see another
Every read and write of customer data goes through a single scoped data layer, so a query without a customer's identity on it is not something a developer here can accidentally write. Every table that holds customer data earns an automated proof before it ships: a second real customer, holding the first one's real identifiers and its own valid credentials, gets exactly what a stranger gets.
What we have not done
A security page with no gaps is a marketing page. These are real, current, and the ones a reviewer would find anyway:
- No formal certification. No SOC 2, ISO 27001 or equivalent. The controls above are real and tested; the audit is not bought until a customer needs it.
- No data processing agreement yet. One is a precondition of the first outside customer, not a thing already signed.
- No choice of data region. Data lives wherever the platform puts it.
- Operator access. Whoever runs this deployment can read the content and the map you load into it. Nothing you store here should be material you would not put in a help centre — and Uiia is designed so that nothing else ever needs to be.
- No sign-in, and no single sign-on. People on the approval desk are real and separate — each has their own key, one can be removed without affecting the rest, and the desk records who approved what — but there is no password, no email verification and no self-service reset, because those need email delivery this product does not have. A key is handed over by whoever runs the workspace, the way the other credentials here are.
- No uptime commitment. There is no SLA and no paid support line.
- Pre-first-customer. Uiia is in active development and has not yet been through an outside security review.
Reporting a problem
No disclosure contact is published on this deployment yet. One is published before the first outside customer — until then this is a development service and should be treated as one.