Ember extensions
An Ember extension is a trusted native package installed into Ember. It is not sandboxed. An extension can run native code and access the user's computer and network. Ember shows this warning before installation.
Extensions use the .ember-extension ZIP format. Version 1 is a local-install format. Ember validates the archive paths and manifest, but it does not establish publisher trust. Restart Ember after installing, enabling, disabling, or replacing an extension.
wireguard-proxy.ember-extension
|-- extension.json
`-- bin/
`-- wireguard-proxy.exeManifest#
extension.json is required.
{
"manifestVersion": 1,
"id": "dev.ember.wireguard",
"name": "WireGuard proxy",
"description": "Routes approved applet requests through a WireGuard tunnel.",
"version": "0.1.0",
"entry": "bin/wireguard-proxy.exe",
"apis": [
{ "namespace": "network.wireguard", "methods": ["status", "proxyFetch"] }
]
}id uses Ember's reverse-domain identifier format. entry must name a file inside the archive. Each declared API names the namespace Ember may make available to applets. Declaring an API does not grant it to an applet.
Applet grants and calls#
An applet requests exact namespaces and methods in its version 2 manifest:
{
"capabilities": {
"extensions": [{
"id": "dev.ember.wireguard",
"namespace": "network.wireguard",
"methods": ["status", "proxyFetch"]
}]
}
}Ember includes approved methods beneath window.ember.extension. The full extension prefix is deliberate. It tells an applet author that this is not an Ember built-in API:
const result = await ember.extension.network.wireguard.proxyFetch({ url: "https://example.com" });At call time Ember checks the signed applet grant, then checks that the named extension is installed, enabled, and declares the API and method. Ember starts the extension entry as a child process, writes one JSON request to stdin, and reads one JSON response from stdout. The request has appletId, namespace, method, and payload fields. The extension must return exit code zero and print one JSON value.
Extensions may return either a direct JSON value or a result wrapper. A wrapper with { "ok": true, "value": ... } resolves to its value. A wrapper with { "ok": false, "error": { "code": "...", "message": "..." } } throws EmberApiError in the applet.
Create a package with npm run extension:pack -- <extension-folder>. Version 1 packages are intentionally local and unsigned. The install screen states that extensions run unsandboxed native code.