This is what Extension Routing or Class of Service is for. To make it so only certain extensions can dial certain things and only use assigned outbound routes.
You are going to very limited on things doing it this way. All the recordings are saved in the same locations. Blacklists are global, mean that is User A blacklists a DID because they don’t want calls from it, it means it is blacklisted for all users including those that want calls from it. Speed Dials/Asterisk Phonebook is global so again if User A creates a speed dial of 1 then all users have that speed dial. If they add a DID to the phone book with a specific name for CallerID, all users get that name if your dipping into the phonbook as a CallerID source.
The other fun caveats, if User A misdials and does something like *211000 to activate FM on their account and they are actually 100 and misdialed if you have a user 1000 they now have FM activated without even knowing about it because a user from a completely unknown company activated on their account by accident.
If user dials *98 and enters the wrong mailbox and that maibox happens to have a basic password like “1234” that happens to be the same password the user calling VM has they could end up in someone else’s voicemail.
There is more to this then making sure Company A can dial certain Outbound Routes or not dial certain extensions from Company B since every user has access to all the apps, feature codes and other global system items that have no real access control via modules because that’s not how FreePBX was designed.
So yeah, when people say you can “emulate it to some degree” they are saying it’s a half-assed implementation that has so many caveats you have to watch for it is a pain in the ass to deal with. And really, do you want your customers figuring out that not only can they get access to other customers users/voicemail/features but also that those other customers have access to their stuff?
Experience is going to dictate no, they would not be happy and it could cost you customers.