Widget permissions
A custom widget starts with nothing. It gets a capability only if its widget.json declares it and the person allows it. What it can actually do is the overlap of the two.
How a widget asks
Section titled “How a widget asks”Declare permissions in the permissions object of widget.json. Omit a key and the widget does not have it.
"permissions": { "backend": false, "node": [], "network": true, "networkHosts": [{ "host": "api.example.com", "methods": ["GET", "POST"] }], "store": true, "required": ["network"]}The capabilities
Section titled “The capabilities”| Manifest key | Name shown to the person | What it grants | Can be switched off alone |
|---|---|---|---|
backend (+ node) |
Run a backend | Starts a sandboxed Node process. node is the allowlist of Node built-in modules it may require. |
No, only by disabling the widget |
network + networkHosts |
Network access | The backend may make requests to the declared hosts. | Yes |
networkAny |
Unrestricted network access | Reach any host over https or wss. Separate from network; never implied by it. |
Yes |
credentials |
Act as you at declared hosts | Requests to a host are sent authenticated with a credential the person connected. The widget never sees the token. | Yes |
webAuth |
Authenticated web session | Sign in to a website in an app window and fetch in that session. The cookie stays in the app. | Yes |
store |
Local storage | The backend keeps its own data between restarts, on this machine (ctx.store). |
Yes |
hubPositions |
Read hub positions | Receives the live positions of other overlay widgets’ hub buttons. | Yes |
| (none, implicit) | Be clickable | Registers the parts of the widget that can be clicked. The overlay ignores clicks anywhere else. | Yes |
Be clickable is held by every interactive widget without declaring it. A widget with "interactive": false does not get it.
Details by capability
Section titled “Details by capability”Network
Section titled “Network”network: true needs networkHosts. Each entry is a host ("api.example.com" or "*.cdn.example.com") or an object with host and methods.
- No
methodsmeans GET only. Use"methods": ["*"]to allow any. - An empty
networkHostslist denies every destination. - A bare
"*"host is refused. UsenetworkAnyfor that, and only when you truly cannot name the destinations. networkModeis"direct"(default; the request leaves from the widget’s frame, fenced to the declared hosts) or"proxy"(the request goes through the app).
Credentials
Section titled “Credentials”"permissions": { "network": true, "networkHosts": ["api.github.com"], "networkMode": "proxy", "credentials": [{ "host": "api.github.com", "as": "github" }]}as names a credential the person has connected, never a secret. Nothing is attached until the person has also connected that credential and authorized this widget to use it. Use it with "networkMode": "proxy"; a direct request never passes through the app, so there is nothing to attach to.
Web session
Section titled “Web session”webAuth is an object: loginUrl (the page the sign-in window opens), cookie (the cookie whose presence means signed in), domain, and fetchPrefixes (the URL prefixes the widget may fetch in that session).
Required or optional
Section titled “Required or optional”List permissions the widget cannot run without in required. Everything is optional by default: a declined optional permission switches that feature off and the widget still runs, while a declined required one means the widget is not installed. You can only require what you declared.
How the person approves and revokes
Section titled “How the person approves and revokes”- Before first load. An untrusted widget triggers a permission review listing what it asked for, marking each line Required, Optional or Every widget (for the implicit one), and what happens if they refuse.
- Allow. In Preferences, Plugins, a new widget shows Needs approval. Allow approves the whole list in one decision; Don’t install declines it and revokes the list. If the widget later asks for more, it shows Wants more access and Allow changes.
- Revoke later. Single permissions can be switched off afterwards under Privacy & Security, while the widget stays enabled. Revoking takes effect straight away.
See Plugins and Custom widgets for the person’s view.