case study / Zoho Creator platform / United Kingdom

A UK healthcare app pushed Zoho Creator to the limit.

The client had spent years delivering compliance support to clinical practices on paper. The plan was to give customers something to log into instead: one application, many independent practices, each seeing only its own records.

Zoho Creator does not provide native record-level separation. It has to be built. In a regulated industry like healthcare, someone also has to prove that it works.

Data isolation between independent organizations sharing a single Zoho Creator application

At a glance

Industry
Healthcare
Location
United Kingdom
Year
2025
Engagement
Design and build of a quality management platform on Zoho Creator, delivered as a customer-facing portal to independent clinical practices operating under CQC regulation. Eight modules, around 80 forms, 140 reports and 70 pages.
Products
Zoho Creator, Creator Portals, Zoho Analytics, Zoho WorkDrive, Deluge
Key takeaway
Creator controls access at the application level, not in the database. With one customer that distinction rarely matters. With dozens sharing an app, it decides the whole design.

01 / The situationMost Zoho work isn't like this.

Dozens of practices, one application, and one bug that would reach all of them at once.

Usually a company adopts Zoho for itself. Its own staff use it, its own data goes in it, and if something breaks, it breaks in one place.

A serious bug in a single-customer build costs that customer its data. The same bug here would expose every practice on the platform at once, and for a company whose business is helping clinics look after regulated data, that is not something you recover from by apologizing.

The application reached eight modules and around eighty forms. There is no single place to enforce the separation between one practice's records and another's. Every record has to check itself each time someone opens it. Add a form a year later and leave the check out, and that form is how the records get out.

02 / How the separation worksThe Principle of Nuclear Containment.

Five conditions checked on every form, and everything that isn't a pass treated as a failure.

Zoho Creator has no row-level security. There is no rule you can write at the database level saying that a given user may only ever retrieve rows belonging to their own organization.

What Creator offers instead is report filtering. A filter decides what a user is shown. It does not decide what a user can reach. If someone has a record's identifier, they can put it in a URL, and that request never passes through the report the filter is attached to.

So separation must be enforced at every independent point a record could be retrieved on the assumption that any one of them could eventually fail:

  • A filter on every report a customer can open, restricting it to their own practice.
  • A stamp written onto every new record identifying the practice of the person who created it, so the record's ownership is established at the moment it exists rather than inferred later.
  • A check as each form loads, working out which practice the user belongs to and comparing that against the record being opened.
  • A refusal to open any existing record that has no practice recorded on it, which should be impossible and is therefore treated as evidence that something is wrong.

All of them work the same way. The system does not look for signs that something is wrong and block those. It requires proof that everything is right and refuses in all other cases. Failure was treated as a "nuclear meltdown."

Five conditions required before a record opens Five checks run in sequence. All must pass for the record to open. Any one of them failing routes to a single denial outcome, which is logged. Record carries a provider ID That provider ID is a valid one User has exactly one user record That record carries a provider ID The two provider IDs match Access denied logged, sent home Record opens
Every condition must hold. There is no list of failures to maintain, because everything that is not a pass is a failure.

The approach has a name — default deny, or fail-safe defaults in the older literature — and its practical benefit is that the check does not need maintaining as new ways to get it wrong are discovered. A record with no practice recorded on it should be impossible. If one appears, the system does not need to have anticipated how it got there to refuse to open it.

The same check then has to run on every form in the application, which turned out to be a harder problem than designing it. That has its own story.

03 / TestingHow do you know your testers actually tested?

Two testers, four accounts, two fictional practices — and two defects planted in the build without telling them.

Two testers were hired independently of one another and paid at a professional rate. Between them they held four accounts: each had a manager login at one fictional practice and a staff login at another, crossed over so that neither person's view of the system was consistent with the other's. Records were labeled so that anything appearing where it shouldn't would be obvious at a glance.

Not everything that looks like a leak is one. A manager at the a practice seeing a colleague's work is correct, and it is much of the point of a shared quality system. Records appearing across practices is the failure that matters. Secondarily, we also needed to make sure that staff at a clinic could not see sensitive records intended for management.

The difficulty is that a test which finds nothing is hard to interpret. "We found no problems" and "we did not look very hard" produce the same report. When the cost of being wrong is a breach of nuclear containment, a clean result you cannot distinguish from an absent one is useless.

Two defects were planted.

Before testing began, and without telling the testers, two known failures were introduced into the build:

  • On one report, the practice filter was removed altogether, so records from more than one practice appeared in a single list. This is the failure that ends the platform.
  • On a second report, the practice filter was left in place and the user filter removed, so a staff account could see everything belonging to its own practice rather than only its own work. Contained within one practice, but still wrong.

Both testers found both, independently, with no reason to think anything had been planted. Both also reported a handful of smaller issues, some of which overlapped and some of which didn't.

That mixture is worth noticing. If they had agreed on everything, it would suggest they were working from the same checklist. If they had disagreed about the two planted failures, it would suggest one of them wasn't reading the system properly. Agreeing on the serious ones and differing on the small ones is what you would expect from two people who were both genuinely looking. Such a signal is nearly impossible to fake.

What that establishes.

Two seeded defects across a large application is a small sample, and it does not prove the other reports are correct. But the alternative standard is not available either.

Suppose a tester opens every report in the system and confirms each one. How does anyone else know they did? We also checked, but the client only has our word for that. If the client also checked, their customers would only have the client's word for it, and so on. Assurance in regulated industries must end in documentary evidence.

At a minimum, our test proved that the people doing the checking were competent and capable of finding a problem when there was one to find, that they did actually look, and that their work was independently duplicated/verified, both by the other tester and by the discovery of the seeded defects.

04 / The audit trailThe record of who looked.

The need for an audit log — and where the build stands now.

Every create, edit, view and delete across the application writes to a central log, and a second table records any occasion when that logging itself fails. Views are included deliberately. In a clinical setting, who opened a record matters as much as who changed it, and a log that only captures changes cannot answer the question most likely to be asked.

This is where the two halves of the build meet. A regulator does not ask whether your access controls are sound, because nobody can demonstrate that during an inspection. It asks who did what, when, and at which practice. Since every form already works out the user's practice before doing anything else, every logged action carries that information implicitly.

Where that leaves it.

The platform is live, with practices being brought on in groups rather than all at once. Compliance records that used to sit across spreadsheets, shared drives and paper folders are now in one system, searchable, each one carrying a record of who created it, who changed it, who read it, and which practice it belongs to.

There is no percentage to report and no before-and-after measurement, because nobody was measuring the old way. What can be said is narrower: the separation between one practice's records and another's is enforced at several independent points rather than assumed once, and whether that enforcement works was answered by a method that produces a result somebody else can check. Keeping it that way depends on every form added from here carrying the same checks, which turned out to be a harder problem than designing them.

Building something on Zoho that more than one organization will use? Let's talk.

Start a Conversation