Security

Security Model

OXP's threat model, defense layers, and what makes it the most secure extension platform.

Security is OXP's #1 design priority and its biggest competitive advantage over npm-style and VS-Code-Marketplace-style ecosystems. This page documents the complete threat model, current controls, and known gaps.

Design Principle

The daemon — not the SDK, not the webview — is the trust boundary. Every method call is re-authorized. Every handle is unforgeable. Every sensitive prompt is OS-native (never webview-rendered). Even a benign extension's webview is assumed compromised in the threat model.

Threat Model

Assets Protected

  • The end-user's machine (filesystem, secrets, network, processes)
  • The end-user's identity (auth tokens, SSO sessions)
  • The publisher's identity (signing keys, publish tokens)
  • The registry's integrity (bundle bytes, version history)
  • The supply chain (source → build → sign → publish → install → run)

Adversaries

AdversaryCapabilityMotivation
Malicious authorPublishes a crafted .oxpSteal data, crypto-mine, ransomware
Account hijackerSteals a publisher's tokenPush malicious update
TyposquatterRegisters @strlpe/checkoutTrick users into installing
Network attackerMitM between host and registrySwap bundle bytes
Compromised registryDB + storage write accessReplace bundles, forge versions

Defense Layers

Layer 1: WASI Sandbox

Extension code runs as a WASI Preview 2 component — no DOM, no Node.js, no syscalls. The only way to interact with the host is through WIT-typed imports mediated by the capability broker.

A Wasm component cannot:

  • Read or write files without fs.read/fs.write permission
  • Make network requests without net.fetch permission
  • Access the clipboard, secrets, or terminal without explicit grants
  • Fork processes — there is no oxp:host/shell interface in v1
  • Import symbols the manifest didn't declare

Layer 2: Install-Time Permission Prompts

Before any extension runs, the user sees every requested capability with:

  • The capability name and description
  • The scope (which files, which URLs)
  • The author's rationale
  • Allow All / Customize / Deny options

Grants are persisted per (publisher, slug). On updates, only new permissions trigger re-prompting.

Layer 3: Cryptographic Signing

Every bundle is Ed25519-signed at pack time. The host re-verifies on install — zero trust toward the registry. Content-addressable bundles (SHA-256 of uncompressed tar) make tampering detectable.

Layer 4: TOFU Key Pinning

On first install from a publisher, the host records their public key in ~/.oxp/trust.json. Subsequent installs from the same publisher must use the same key. A different key triggers KEY_PINNING_VIOLATION — the install is blocked.

The registry also pins keys server-side on first publish.

Layer 5: Scoped Tokens

Publish tokens are scoped (publish:@handle/* or per-package) and expire after 90 days by default. The rotation endpoint provides a 5-minute grace window for in-flight publishes.

Layer 6: Bundle Policy Enforcement

assertBundlePolicy runs at both CLI pack and registry upload:

  • **ui-v1 bundles** — no executable code allowed (no .js, .ts, .wasm, .sh, .exe, etc.)
  • **component-v1 bundles** — only a signed .wasm + .wit
  • Verified-only capabilitiesterminal.* and process.kill denied to unverified publishers
  • Unknown permissions — rejected by catalog validation

Layer 7: CSP for Webviews

Every rendered webview gets strict Content Security Policy:

  • default-src 'none'
  • Per-render nonce for scripts
  • connect-src 'none'
  • frame-ancestors 'none'
  • No inline scripts

Layer 8: Resource Limits

Per-call wall-clock cap (default 100ms) prevents runaway components. Memory cap (default 64 MiB) bounds resource usage. Exceeding limits disposes the instance.

What's Safe Today

  • Building and publishing your own extensions
  • Installing extensions from publishers you personally trust
  • Using ui-v1 declarative mode (no code execution path)
  • Relying on the WASI sandbox to contain honest mistakes

Known Gaps

  • No publisher domain verification yet (Phase B)
  • No bundle static analysis beyond policy checks (Phase B)
  • No revocation mechanism for known-bad bundles (Phase C)
  • No reserved namespace enforcement (Phase B)
  • Wall-clock time limits only — real wasmtime fuel coming in Phase B