Salesforce does this with a combination of web components, with a patched up ShadowRoot so that code with a reference to the shadow root can't walk into the rest of the document, and a secure evaluator function related to SES (Secure EcmaScript) to limit the globals the untrusted script has access too.
The secure evaluator is wild. I think this is the heart of it: https://github.com/Agoric/realms-shim/blob/v1.1.0/src/evalua...
There's also an idea for isolated web components to solve this in the platform: https://github.com/WICG/webcomponents/issues/1002