The architecture,
before the sales pitch.
If you are the technical lead being asked whether this is real, this page is written for you. Isolation, data access, the security posture, the extension model, and what happens if you ever decide to run the whole thing yourself.
Is this multi-tenant?
Two different questions hide in that word, and for WebEdify the answers are opposite ones.
How your application is hosted: no, deliberately. WebEdify is delivered as managed hosting, and every client gets a dedicated environment. There is no neighbouring tenant whose data sits in your database, whose traffic shares your capacity, or whose incident becomes your outage.
- Your own data stores.
Your application's database holds your records and nobody else's. - Your own release timing.
What you need gets built for you, not queued behind what is safe for everyone else. - Your own capacity.
Performance and resources are staged per client, so scaling you up is never a change to somebody else's environment. - Your own configuration.
Including which AI provider you use, or whether you use ours at all.
What you can build on it: yes, natively. Multi-tenancy for your tenants is a platform default, and the next answer is how.
Why this matters more than it sounds
Being someone else's tenant is cheaper for the vendor, which is why almost every platform is sold that way. The cost comes back to you as constraints: shared release cycles, feature requests weighed against every other customer, and a data-isolation story that is ultimately a promise about somebody else's query filters.
The architecture is not the problem — we hand it to you as a default. Carrying it at our layer as well is what we chose not to do, because the customers we want are the ones for whom that trade does not work: regulated data, real integration surface, and requirements that are genuinely theirs.
Could we run it ourselves if we wanted to?
Yes, and that is deliberate. There is nothing proprietary in how your application runs: standard .NET against standard databases, on infrastructure your own team could operate. Commands and templates are plain text files in your source control, not rows in a vendor's database.
If you ever decide to take hosting and support in-house, we license the platform libraries so your application keeps running, and we write that into your agreement rather than leaving it as a promise on a web page. Clients stay because we run it for less than it costs them to staff it — not because leaving would be hard.
Can you build a multi-tenant product on it?
Yes, and the part worth understanding is that you do not build the tenancy. MACRIM used to carry two layers of it — ours, and our clients' — and WebEdify removes ours while handing you the other one as a platform default.
Tenant identity is half of the primary key on every data store. segment:catalog
is the default key format, so the tenant becomes part of the composite primary key on a SQL
table and the partition key path on a Cosmos container — not a discriminator column somebody
has to remember in every query. The same shape holds across SQL Server, Cosmos, Turso and
SQLite.
Configuration resolves per tenant as well. Each of your tenants can carry its own connection strings, settings and service endpoints, so one can share a database with its neighbours while another sits in a database of its own — without an application change. Tenant resolution runs from the authenticated user first, then the application default, so isolation is a property of the platform your code runs on rather than a convention your team has to maintain.
"primarykey": "segment:catalog"
CREATE TABLE [Users] (
segment NVARCHAR(55) NOT NULL,
catalog NVARCHAR(55) NOT NULL,
jsondata NVARCHAR(MAX) NOT NULL,
CONSTRAINT PK_Users
PRIMARY KEY (segment, catalog)
)
What a table looks like when the platform creates it — the default, not an option someone
enabled. On Cosmos the same declaration sets the partition key path to
/segment. This is why a product company can put one application in front of a
hundred customers without hand-rolling isolation, and why a tenant can be backed up,
restored or moved on its own.
Where does your data go when your users talk to your AI?
By default, nowhere that contains your values. WebEdify has four explicit levels of data access, and the default is structure-only: the assistant sees field names, hierarchy, and record counts — never the data itself.
Structure only
The assistant can execute a command and receive back only the shape of the result — field names, hierarchy, record counts. No values. Ever.
results ($) [15 children] contact [id, name, surname, email, taxid, dob, status]
Fifteen records. Every field name. Zero actual data.
Render without sharing
The AI authors markup. Your server executes it. The rendered result travels from your server directly to your user's browser.
The user sees their data. The AI never did. This is not a privacy feature layered on top of the rendering system — it is the rendering system.
User-confirmed sharing
When the AI genuinely needs to reason over values — to summarise or compare — it must ask. The user sees a confirmation prompt before anything is transmitted.
The framework also applies its own filtering to commonly sensitive fields, even inside a share the user approved.
Explicit developer grant
When a developer deliberately wants the AI to have direct access to a specific, scoped result — a safe aggregate, a pre-filtered summary — they declare a tool that does so.
Intentional, scoped, visible in the markup, and auditable. Not a default that leaks by accident.
The platform ships locked down, not left to the project
Secure defaults belong in the framework, where every application inherits them, rather than in a hardening checklist somebody works through per project. The short version of what that means here:
- Nothing is reachable until it is declared.
External command access is default-deny at every HTTP entry point, and every exposed command declares the roles that may call it. - Ownership is checked, not trusted.
Record ownership and tenant boundaries are enforced server-side rather than taken from the request. - Abuse paths are closed.
CSRF protection on cookie-authenticated changes, rate limits on public sign-in and form posts, and state-changing requests refused over GET. - The same baseline everywhere.
Security response headers, safe production errors, and access control are part of the shared host every application runs on.
And the operations underneath it
Patching, backup verification, monitoring, and access control run as standing practice across the whole managed book — a team looking after 50+ customer networks and systems today — not as a checklist completed once at onboarding.
Your security team will have more questions than a web page can answer, and that is the right instinct. Send us the questionnaire and we will walk them through the controls and the architecture under NDA.
Extend the framework. Never fork it.
Every low-code platform demos beautifully and then hits a wall the first time a real business requirement shows up. The wall is what you are really evaluating. WebEdify does not have one, because underneath the declarative layer is the full .NET platform and every major behaviour is a named interface with a clean contract.
Extension means implementing an interface and referencing the assembly. A factory service scans referenced assemblies at startup and registers what it finds — no wiring, no registration code, no configuration file to update.
| Interface | What it adds |
|---|---|
ITag | A new template directive, available everywhere immediately |
IProcessor | A new named step in the command pipeline |
IRestClient | A custom HTTP integration |
INodeRepository | CRUD and search against any new data source |
IAiChannel | A new AI provider, including one you host yourself |
IAiTool | A new tool library for the assistant |
A processor built for one client today keeps working against future platform versions, as long as the interface contract holds — which it will. Extensions live in your own libraries, on your own versioning, and never create upgrade conflicts.
## process-eligibility ### Steps **get** patient from default **eligibility** check with payer - plan: `` - retries: 2 **save** patient to default
One custom processor turns a payer API call, response validation, record update, and transaction log into a single readable line — reusable across every client in that vertical, maintained in one library. This is how a team packages its own domain expertise instead of rewriting it per project.
Changes without a deployment window
File resolution is version-aware. A developer works against their own isolated version, previews it in the live environment against real data, and promotes when it is right. Production users see nothing until then. There is no environment swap and no release pipeline standing between a fix and the people who need it.
Nothing to build, nothing to upgrade
- No React, no jQuery, no npm.
HTML is rendered server-first and hydrated by the platform's own lightweight script. - Rich primitives included.
Forms, tables, charts, dialogs, and live relays are tags, not libraries you assemble. - Plain files, plain Git.
No proprietary visual designer holding your application hostage in a database. - No framework churn.
There is no bundler config to maintain and no major-version migration waiting for you in eighteen months.
<@relay path="patient-detail" rename="p" id="" /> <form action="/api/command/save-patient" method="post"> <input type="hidden" name="id" value="" /> <input type="text" name="name" value="" /> <button type="submit">Save</button> </form>
What you are probably comparing us to
Each of these is the right answer for someone. Here is who.
Staying where you are
A content platform or legacy application with a hosting provider bolted underneath.
Right for you if the application is essentially finished and your roadmap is maintenance.
Where we differ: content management is included here as well, but it lives in the same application as your data, dashboards and transactions instead of beside them. The cost of the other choice is paid later, in customisations that get harder every year and a security surface you inherit rather than choose.
A custom build with an agency
Bespoke React or MVC, delivered by a partner and then handed to you.
Right for you if your product is genuinely novel and the interface is the differentiator.
Where we differ: you get most of that flexibility without funding the scaffolding — auth, CRUD, tables, charts, dashboards and AI — from scratch, and without owning a build pipeline afterwards.
A BI or low-code platform
Tableau, Power BI, Domo, or a drag-and-drop app builder.
Right for you if you need broad general-purpose analytics spread across many departments and nothing more than reporting on top of it.
Where we differ: integrations built against your system rather than picked from a gated catalog, self-service that reaches past reporting, and a dashboard that can become a transactional feature tomorrow without changing platforms.
Your requirement is not queued behind anyone else's
In multi-tenant SaaS, the feature you need is weighed against what is safe for every other customer on the platform. That is the real cost of being someone else's tenant, and it is why vendor roadmaps are measured in quarters.
You are not in a pool, so there is no queue. Most of what clients ask for is a configuration change or a short piece of declarative work — days, not release cycles. When something genuinely is not built yet, you get a date you can hold us to instead of a place in line.
Why this is possible at all
A capability that would be a quarter of platform work elsewhere is usually a command file and a template here. That is the whole point of the declarative model: the distance between "we need this" and "it is running" is short enough that saying yes is the normal answer.
Questions we get in every evaluation
Answered here rather than in month three.
How quickly does our team get productive?
In days. The declarative layer exists precisely because an LLM writes it reliably — substantially more reliably than it writes equivalent MVC or React. The assistant works in the same files your developers do, proposes changes they can read and check, and teaches the idiom while it builds. Your analysts get the same benefit from the other direction: describe the view you want, get a working one, and read the markup behind it. There is no certification track standing between your team and their first useful change.
How do integrations actually work?
They are built against your real system rather than picked from a catalog. There is no connector marketplace here and no per-connector subscription — an integration is written against the actual API you have, which is usually short, AI-assisted work, and it belongs to you once it exists. Where another vendor points you at their roadmap, we build it.
Are you SOC 2 certified?
The security and compliance practice behind it runs today across 50+ customer networks and systems, and the platform ships the controls described above. Formal certification is in progress, and in the meantime we will walk your security team through the controls and the architecture under NDA.
All things done for edification.
We exist to build up developers, teams, and organizations through faster, cleaner, more maintainable software — and to leave every team we work with more capable than we found it.
Talk to us