# Security model

This package has two intentionally different isolation levels.

- `createMicroAppInstance` is for trusted applications. Its Proxy/Shadow DOM model provides compatibility, cleanup tracking and style isolation, but is not a browser security boundary.
- `createIframeMicroAppInstance` is for untrusted or independently governed applications. It defaults to `<iframe sandbox="allow-scripts">`, which gives the child an opaque origin and prevents access to the host DOM, cookies, storage and navigation APIs.

## Secure iframe defaults

- Do not add `allow-same-origin` together with `allow-scripts`. The runtime rejects that combination unless `dangerouslyAllowSameOriginWithScripts` is explicitly enabled for a trusted child.
- Keep the permissions-policy `allow` attribute empty unless a child genuinely needs a browser capability.
- Host-to-child props and child-to-host events must be structured-cloneable data. Functions, DOM nodes and shared mutable objects are deliberately unsupported.
- The child must use the `@epochx/micro/iframe-sub-app` adapter when `bridge: "required"` is used. Set `bridge: "none"` only for unadapted third-party pages; lifecycle updates are unavailable in that mode.
- The child server must permit framing through `Content-Security-Policy: frame-ancestors` and must not send a conflicting `X-Frame-Options` header.
- The host and child should each deploy a restrictive CSP. This runtime does not require `unsafe-eval`.

No client-side mechanism can safely execute hostile code in the host JavaScript realm. Use the iframe mode for that boundary, and use separate origins when the child needs storage or credentials.


## Message boundary

Iframe child events are denied unless listed in `allowedEvents`. Keep payload validation in `validateEvent`; never pass received values directly to HTML, URLs, SQL-like filters, or authorization decisions. The runtime enforces message-size and event-rate limits and closes a violating bridge.
