Security
Keeping every customer's data apart is this product's central claim, so it is written out here in enough detail to be checked rather than believed. Every statement below matches something in the system.
Every customer gets a space of their own
Most services keep every customer's information in one big list and tell them apart with a label on each entry. That works until one request forgets to check the label. MemoryAgent gives every workspace a space of its own instead: separation you can point at, rather than separation that holds only for as long as every request remembers a filter.
Nothing is kept in the general area a stray request would land in, and our own platform records are kept somewhere else again. A request that somehow lost its way finds nothing at all, rather than quietly reaching real data belonging to somebody else.
A workspace is one boundary, and you choose what it means: one per customer, one per environment, or one per project. Crossing from one to another is not a permission we withhold — there is no request that spans two of them.
A key resolves to one space, on our side
An API key resolves on our servers to an account, a workspace, a role and the actions it may take. The client sends none of that. A request can narrow itself to one app or one project, and nothing a client can send widens it.
- Master keys reach every workspace inside their own account, and nothing beyond it. They are for administration.
- Workspace keys reach exactly one workspace, and should carry ordinary traffic.
- Role keys reach one workspace with one role — a reader can read, a writer can read and write.
There is no credential that spans accounts, and no role that sits above them. That also means we have no way to act as you, which is by design and not an omission.
The boundary holds when connections are shared
Connections to the database are pooled and handed from one piece of work to the next. Each piece of work names the one space it may touch, and that permission expires the moment the work finishes — so it cannot travel onward with the connection to whoever is handed it next.
The names of those spaces come from our own register of workspaces. Not one of them is ever built out of something a request contained.
The suite that proves this runs on every change against a real connection pool, deliberately kept small so that connections are reused constantly. A test against a private connection could never show the fault it exists to catch, so passing one would prove nothing.
Credentials
- API keys are stored scrambled. A key is shown once, at the moment it is created, and cannot be retrieved afterwards. Replacing one issues a new key and retires the old.
- The model-provider key you store with us, if you store one, is held under AES-256-GCM encryption and decrypted only to pull facts out of your own workspace's conversations. A copy of our database alone does not yield a usable key.
- Passwords are scrambled by the authentication library. We never hold one in a form we could read.
- A key is never placed in a web address, never written to a log, and never sent to an analytics or session-replay tool. Nor is one ever shown again after it is created — a list of keys returns the first few characters and a label.
In transit and at rest
Everything crossing the network does so over TLS. At rest, the data sits on storage provided by Railway; the provider credentials we hold on your behalf are encrypted by us on top of that, so the two do not fail together.
Backups, and the drill
Two independent mechanisms, because they fail differently. Whole-disk copies are fast and complete: daily kept for 6 days, weekly for 27 days, monthly for 89 days. A nightly portable copy is kept for 30 days.
The portable copy is the one that gets proven. It is checked against its published fingerprint, restored into a scratch database, and then queried — because a backup that restores but cannot answer a search has not been restored. A copy that arrives without its fingerprint fails the drill rather than skipping the check.
A backup nobody has restored is a hypothesis, so the drill runs against real copies rather than against a description of one.
Deletion
Deleting a workspace removes everything in it, outright. It cannot be undone, and it gives up any later re-processing of those memories. Backups taken beforehand hold the data until they expire on the schedule above.
How a change reaches production
Every change runs the same ladder of gates: type checking across the whole codebase, a check on the boundaries between its parts, unit and integration suites against a real database, and the separation suite. The pipeline invents no new idea of correct — it removes the assumption that somebody ran the checks by hand.
The integration stage reproduces the local stack exactly, shared connections included. A pipeline that shared connections differently would let the separation suite pass while the product leaked.
Releasing is a merge into a deployment branch: a reviewable change with an author and a time, rather than a command someone ran on a laptop.
Technical and organisational measures
The same claims once more, with the mechanism named, for a reviewer who wants it. One dedicated PostgreSQL schema per customer — no shared table, and no tenant_id column for a query to forget. Every query runs inside a transaction that issues SET LOCAL search_path for that schema, never a session-level SET, which would survive the commit and follow a pooled connection to the next customer in line; the isolation suite runs against a real connection pooler in transaction mode precisely to catch that, and a direct connection could not exhibit the bug at all. Schema names come from the tenant registry and never from a request. public is left empty and platform tables live in platform, so a query that lost its search path finds nothing rather than somebody else's data. Erasure is DROP SCHEMA: the tables cease to exist, it is irreversible, and it forfeits re-processing of those rows for good. Retention sweeps mark rows rather than deleting them. Audit records survive an erasure and are de-identified in the same transaction. TLS in transit; AES-256-GCM envelope encryption for the provider credentials we hold.
What we do not claim
We hold no security certification today.
There is no SOC 2 report and no ISO 27001 certificate, and we would rather say so plainly than let a badge-shaped absence imply otherwise. There is no service-level agreement and no paid bug-bounty programme either.
What we do have is above, and every item of it matches something you could ask us to demonstrate.
Reporting a vulnerability
Send it through the contact form, choosing the security option. Tell us what you did, what you saw and what you expected. A request identifier from an API response helps far more than a screenshot does.
We will acknowledge the report, tell you what we found, and tell you when it is fixed. We will not pursue legal action over research carried out in good faith against your own account and your own workspaces.
Do not test against another customer's data, and do not run load or denial-of-service tests. If you think a test needs to cross that line, ask first — the answer is more often yes than you would guess.