If you sell an AI agent to a hospital, the demo is the easy meeting. The hard one comes a few weeks later, when a security reviewer sends a questionnaire and the deal stops moving until you answer it.
I built Inhold for that second meeting. It is a context layer for agents: memory, approved skills and corrections, kept in the end customer's own cloud account, with every read and write checked against their policy and logged. Before writing code I wrote down the 20 questions reviewers ask about agent data. They live in security/TOP20_ANSWERS.md in the repo, and a CI test checks that every answer points at a real file in the evidence pack.
Here are the ones that come up first, with where Inhold stands today. Some answers describe the AWS install, which is still in build. v0 runs on one machine with SQLite and a synthetic hospital called Contoso General Hospital. I will say which is which.
Where does the agent's memory live?
This is always first. The reviewer wants a place they control. The design answer is Postgres in private subnets in the hospital's own AWS account, encrypted with their KMS key. That install is designed and in build. Today v0 stores memory in a SQLite file on one machine. A database adapter is in place so Postgres can sit behind the same service.
I would rather say that plainly than have a reviewer find it.
Does any data leave our account?
Inhold has no telemetry, no licence server and no update check. CI runs the service and the demo with outbound connections blocked, and the build fails on any attempt.
There is a catch I always state. The vendor's agent receives whatever the policy lets it read. If that agent runs in the vendor's cloud, that data leaves the hospital's account. Inhold controls what the agent can read. It does not control where the agent runs.
Who decides what an agent may read?
The hospital does, through a policy bundle: a JSON file their team owns and can diff. Every call is checked on three things: who is asking, for what purpose, and what label the data carries. Anything the bundle does not allow is denied.
The purpose part matters most to reviewers. A prior authorisation agent and a billing agent can run in the same install. Each call names a purpose, and a purpose reads only the labels and source purposes its entry lists. An agent cannot claim a purpose it is not registered for, and over MCP the purpose is fixed for the session, so a prompt injection cannot talk the agent into switching.
What gets logged, and can the log be altered?
Every policy decision writes one audit row, allowed or denied. The row records the actor, action, object, labels, purpose, the SHA-256 of the policy bundle in force, the engine hash and a session id. Deny rows carry the reason.
Rows are append-only and each one carries the hash of the row before it. The application cannot edit them. A database admin with full rights can still rewrite the whole chain, so Inhold writes anchors, signed copies of the chain head, outside the database. In v0 those anchors sit on the same host, which is weaker. I wrote a separate post on what the chain proves and what it does not.
How is PHI identified?
This is the answer reviewers push on hardest, and they should. At write time, local pattern detectors label MRNs, dates of birth, ICD-10 codes, NPIs, member ids, SSNs, emails and phone numbers. Nothing is sent out to classify it. Callers can add labels and can never remove one.
The patterns miss a lot. A patient name written in a sentence, an address, or an MRN without its "MRN" prefix is not labelled by patterns. An optional local name model, loaded from disk, catches most names on our synthetic test sets and still misses some. Addresses and free-text dates are missed either way. So the real control is the bundle: a purpose that handles patient data sets PHI as its default label, and any write that names a patient as its subject is PHI whatever the tagger finds. I tell reviewers to treat the tagger as a backstop.
What happens when a nurse corrects the agent?
The correction is stored with a diff and becomes a draft skill. A principal with the skill approver role must approve it before any agent sees it. The default bundle gives that role only to people. Agents cannot write corrections at all; one of the red-team cases checks that.
There is a known gap here. A person with the approver role can approve their own correction. The demo does exactly that. It is on the gaps list.
Is Inhold a business associate?
Our position is no for the software alone, because the software sends us nothing and we hold no account in the install. Support that needed access to PHI would be under a BAA. A lawyer has not reviewed that position yet, and I mark it that way everywhere it appears.
What the reviewer gets
Inhold exports an evidence pack. It holds the audit export, a chain verification result, the active bundle and its hash, the anchors, the threat model and a control map against eight lines of 45 CFR 164.312 plus the minimum necessary standard. MANIFEST.json lists every file with its SHA-256. inhold verify-pack checks a new pack against one you kept from before, because a pack cannot vouch for itself.
On the security page, 16 of the 20 answers are marked in v0, three are designed and one is a gap. There are 14 items on the known gaps list, including no outside security review and no SOC 2 report.
Why I publish the gaps
Reviewers have read a lot of vendor answers. The fastest way to lose one is a claim they can disprove in a test environment. Every answer on our site carries a status and names the file that backs it. The repo goes public on 9 November 2026.
We have no customers yet. If you sell agents into hospitals and a deal is stuck in review, I would like to see the questionnaire.