© 2026 Medoya LLC
Powered by voilamia
Subscribe to receive new insights





The agent surface is not an integration sitting beside the application. It is the same set of doors a person passes through, and it grants no access a human could not have been given.
They do not all arrive the same way. A visitor asking the site a question, an editor working in the admin chat panel, a coding assistant on someone's laptop speaking the Model Context Protocol, and a customer's own script carrying a minted token are four different front doors. A tool call from the outside assistant becomes a loopback request to the very same internal route, carrying the very same credential the script would, so the rules have one implementation rather than four. Each credential also carries its own rate-limit window, so an assistant that misreads a response and starts looping exhausts nothing but itself.
A staff member mints a credential inside their own account, re-entering their password. The agent then acts as that person, never as a shared service account, and the credential expires on a clock and dies on one click. Whole collections are refused at the edge, according to how wide the credential is, before a request reaches the application at all. Every collection past that point resolves read, create, update and delete from a matrix an administrator edits in the admin, not from code someone has to redeploy.
Writes land as drafts, and a standard credential cannot publish at all: the publish field is refused before the write happens. A credential its owner has deliberately widened publishes as the person who minted it, because at that point it is only doing something they could have done themselves. Draft is the default rather than a ceiling, and which one a given assistant gets is decided per credential, not once for the whole platform. Either way every write, and every read of personal data, is recorded with who it acted as and which records it touched.
Below all of it sits a floor: user accounts, roles, API credentials and stored provider keys. No scope opens them, including the owner's own full-permission token. An agent here can be trusted with a great deal and still have no path to granting itself more.
One repository builds one image per site, pinned to an exact digest so that what was tested is what runs. A site's database name and its media storage are computed from the site's own name. There is no setting that points them elsewhere, because a setting is a thing that can be wrong at three in the morning. The database stamps its owner on first use and refuses a stranger.
A deploy is one transaction rather than a sequence of hopeful steps: pin the image, back up the database, apply the schema changes committed in the repository, then hold the new container at a gate until it proves four specific things. That it reports the exact version that was built. That it is the site it should be. That no migration is still pending. That it genuinely renders pages, checked from inside the container. The gate retries for three minutes before giving up, because a cold container answering slowly is not a broken one, and it rolls back only if that deadline passes with something still unproven. Schema reaches a running site only through a migration file that someone wrote and someone reviewed.
Genwork sits behind Cloudflare, and that is a structural choice rather than a CDN habit. TLS, the firewall rules and the bot filtering all happen before a request is ours to get wrong. The administration area is gated at that edge against the customer's own identity provider, so the multi-factor policy their security team already runs is satisfied before a login form is reachable, and the application's own password becomes a second factor behind it. The origin publishes no public ports at all: traffic arrives through an outbound tunnel, so there is no address to scan and no port to knock on.
Underneath that, personal data is encrypted field by field at rest with AES-256-GCM, across subscribers, orders, tickets, donors, volunteers, form responses and signed documents, with a keyed index so a person can still be looked up without decrypting the table. Secrets an administrator types in sit under a separate key with per-feature derivation. Card numbers never arrive in the first place, because the payment provider holds them, so there is nothing there to lose.
Every administrator login and every agent read and write is recorded, on a retention clock, with anything that looks like a secret redacted before it is written down. Each deployed site is scanned weekly, a smoke probe built from the platform's own configuration plus dependency and static analysis, with an OWASP ZAP baseline and nuclei run on demand. That is evidence between audits rather than a substitute for a penetration test, and the posture document says so, listing what is missing beside what is in place. A control inventory that records only the wins is not an inventory.
None of this is patient data, and that is deliberate. A festival's ticket buyers and a museum's members are a real obligation under Quebec's Law 25 and nowhere near the stakes of a medical record, which makes them the right place to make these controls routine. The encryption, the access matrix, the audit trail and the answers to a vendor questionnaire are the same shape either way. Only the cost of getting them wrong changes.
Medoya Labs
Built on a proven headless CMS, then layered: four boundaries a build gate keeps honest, a permission floor no AI credential can open, personal data encrypted field by field, and one codebase running many sites on infrastructure it derives rather than reads. TypeScript on Payload and Next.js, since March 2026.
Genwork is the engine behind the websites we build, and it begins with a deliberate decision not to write a content management system. It is built on Payload, a mature open-source headless CMS, with Next.js in front of it and PostgreSQL underneath. The document model, the field types, the draft and version history, the localisation, the access-rule engine, the administration interface and the migration machinery are proven parts we did not reinvent, and they are much of the reason the rest of this holds together.
What Genwork adds sits above that line: how a page is composed out of blocks, how a domain is kept out of the framework, how one codebase runs many sites without their data ever meeting, how a deploy proves itself before it takes traffic, and what an AI agent is allowed to do. A good CMS gives you documents, versions and permissions. It does not tell you where a festival's idea of an event belongs, or what a credential should be able to reach at three in the morning.
It exists because of a question that kept coming up in client work. Everyone wants an assistant that can maintain their site. Far fewer can say what that assistant would be allowed to do, how anyone would find out afterwards what it did, or what stops it from widening its own access. Genwork is one answer, written out in full, at real scale.
Every practice we put in front of a client is tried here first: the layering rules, the agent permission model, the migration discipline, the encryption, the deploy gate. Not in a sandbox that can be abandoned when a decision turns out badly, but on a system real people use, where we carry the cost of being wrong. That is what makes the advice worth anything.
Plenty has been reverted. Per-site build caches were built, measured and thrown away when the numbers showed they saved nothing. A popup system was deleted once it was clear that every popup was really a form. A convenient path for copying a production database into a preview environment was removed on purpose, because convenient is exactly how the wrong data reaches the wrong place. A practice that has never been allowed to fail is a preference, not a practice.
A festival's idea of an event and a store's idea of a product are both real, and neither belongs anywhere near pages, media and permissions. So the framework at the bottom knows nothing about any industry. The domain sits in a template above it, the commercial features are plugins above that, and a customer's own site is the thinnest layer of all: it may choose and configure, never define.
Dependencies run one way only, and that is the part worth stating out loud. Each of the four rules is a script that runs on every push, because layering that is only written down is layering that drifts within a quarter.
The fair question is what happens when one client needs something no other client wants, and the answer is that it costs more than a setting. A site's own layer may pick a theme, a page preset or different wording, but it may not invent a field. That work belongs in a template, behind a flag only that client switches on, and it ships with the migration that creates the column. Individual blocks stay narrow for the same reason: one lives in the template that needs it and is simply absent everywhere else, so nothing has to be made vague and multi-purpose in order to be allowed.
The trade is worth naming rather than hiding. Schema drift is checked once, against a configuration with every feature switched on, and that check is only trustworthy for as long as every real site is a subset of it. Let a single site declare something the platform has never seen and the check quietly stops meaning much for any of them. So the boundary is not tidiness. It is what keeps one verification honest across every site at once, and the price is that a bespoke field is a deliberate change rather than a quick one. For work that touches a schema other people's data lives in, that is the right way round.
Pages render on the server and ship no JavaScript unless a block genuinely needs it. Languages are native to the content model rather than a translation layer laid over it, so a page states its own language and its links carry the right one. Theming is content an administrator edits, dark mode included. All the architecture above is the team's concern; a reader should only ever notice that the page is quick and says the right thing.
This is the same problem our clients have, at lower stakes. Your engineers want agents inside the systems that hold patient data, and your security review wants to know what that agent may touch, acting as whom, how the data is protected at rest, and how you would prove any of it after the fact. Genwork is where we work that out at full scale on our own risk before recommending it on yours: least privilege by construction, a floor the credential cannot lift, encryption that does not depend on anyone remembering to switch it on, a human approving anything that ships, and an audit trail that answers the question instead of gesturing at it.
In production on client sites, including this one. TypeScript, Next.js, Payload CMS and PostgreSQL, self-hosted behind Cloudflare. The core layer is open source by design; the public distribution is not out yet.
Book a free 30-minute readiness review. Bring your team's current AI tool usage and one workflow you want agents in. Leave with the three blockers and the first step.