Hi Jeremy,
Your original question made it sound like you might be using the notebook purely as a dashboard interface with some level of point-and-click interactivity. This should be doable using the advice you have already received, provided you have good control of your users work environment. If you do not, then you must consider that any restrictions implemented in client-side JS can be circumvented by browser extensions. This is before you even consider the screenshot hole, which lately also includes cell phone photos of the screen.
Now that you have added the requirement that users be able to input and execute normal code cells, you may need to rethink your security model even further. A few lines of Python is quite adequate to upload a dataset to an outside server, load new JS code into the browser, or make arbitrary changes to locally writable files. In the general case, preventing data exfiltration is a hard problem, even with very strict controls on the users.
My advice, based on my organization's work to build a system with similar requirements, is this: if you want to use a system as flexible as Jupyter, forget about detailed control of how your users interact with data. Instead, focus your technical effort on detailed logging of which users have been given access to which data, educate your users about acceptable data use, and make it crystal clear that they will be held accountable if data is mishandled.
Regards,
Michael