Skip to content

Security model

A plugin never gets direct access to files, the database, secrets, or the network. Everything goes through a gateway that checks a chain of conditions on every call.

Gateway
installed → enabled → compatible → capability granted →
→ scope → side-effect → domain adapter

Any ambiguity at any step means denial — the system is fail-closed. A permission declared in the manifest is not the same as a granted one: the user confirms rights at install, and they are re-checked on every call.

  • Third-party code runs in a separate process (QuickJS-NG engine) owned by the Yttri backend — one process per active plugin. The sandbox has no fetch, WebSocket, DOM, Node or Tauri APIs: they are absent, not merely discouraged. The only way out is the typed YttriHost, and it goes through the gateway.
  • A plugin crash or hang takes down neither Yttri nor neighbouring plugins: the process is killed, the call fails, and nothing is replayed.
  • Network access is limited to manifest-declared hosts (allowlist), and response body size is capped.
  • Secrets are isolated per plugin and encrypted; other plugins’ secrets are unreachable.
  • Plugin logs are sanitized of sensitive data.

A plugin’s mutating tools, when used by the AI agent, require user confirmation per call by default. Run without confirmation is a deliberate choice for a trusted plugin and a separate toggle in its settings.