© 2026 Medoya LLC
Powered by voilamia
Subscribe to receive new insights
Medoya Labs
Genwork is the engine behind the sites we build and our ongoing test bench: a proven headless CMS underneath, enforced layering above it, a permission floor no AI credential opens, and personal data encrypted field by field.



Genwork is in production today, running sites for clients as different as a music festival and a consulting firm. Genwork is the engine behind the websites we build, and it starts from 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 and PostgreSQL underneath. We did not reinvent the document model, field types, drafts and version history, localisation, access-rule engine, administration interface or migration machinery. They are proven parts, and they are a large part of why everything built on top holds together.
What Genwork adds sits above that line: how a page is composed from blocks, how industry-specific concerns are 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.
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 and running at real scale.
Every business has its own core concepts, whether that is a booking, a product, a listing or a case. They matter, but none of them belongs next to pages, media and permissions. So the framework at the bottom knows nothing about any industry. Business-specific structure lives in a template above it, commercial features are plugins above that, and a customer's own site is the thinnest layer of all: it may choose and configure, but never define.
Dependencies run one way only, and that is the part worth stating out loud. Every layering rule is a script that runs on every push, because layering that is only written down drifts within a quarter.
The fair question is what happens when one client needs something no other client wants. 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. Blocks stay narrow for the same reason: each one lives in the template that needs it and is simply absent everywhere else, so nothing has to be made vague and multi-purpose just to be allowed.
The trade-off 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 while every real site is a subset of it. If a single site declares something the platform has never seen, the check quietly stops meaning much for any of them. So the boundary is not about tidiness. It 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. When a change touches a schema that holds other people's data, that is the right way round.
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.
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 call. Tell me which AI tools your team uses today and one workflow you'd like an agent to take on. You'll leave knowing the three biggest things in your way and a first step for each.