There is no "Correct way", there is a "way that works best for your intended purpose".
I would recommend you separate the data file into a separate file (data separation model), and roll out your interface updates independently. This way you can keep separate data files for each set of users, with never a cross-contamination danger, and also roll out interface updates across all systems easily.
You might want to roll your own login system that's stored in the data file as well.
The downside would be that updating your data file will require more time to roll changes across all files. If your CRM is in it's senior years of development without a lot of changes happening, then I'd definitely recommend this route.
The other route would be to build in a migrator that imports data into an "update" file, this would allow you to keep each group's CRM separate, and when you need to roll out an update, you point the data source to that group's file, run the migrator, take down their old file, and host the update. Assuming you use the same file name, all shortcuts should still work.
For security though, it sounds like you already want to have separate files for each group's CRM, and do not even want to try separating the data out in-app.
Remember to take updates into account for what you charge, as it will be more time consuming to update X number of files instead of 1 file.
Yeah, a little CFIF goes a long way, eh?
I would like to have "dynamic" external file sources. contacts = abc_contacts or def_contacts or ?? based on the name of the "opener/interface" file being the same prefix (or using a variable as we have for other file paths).
Set Variable ($contacts = $prefix & "contacts")
OPEN FILE ($contacts)
Put in a request!