> For the complete documentation index, see [llms.txt](https://docs.getvenora.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.getvenora.tech/plugin-api/plugin-permissions.md).

# Plugin permissions and capabilities

Part of the [Community Plugin API specification](/plugin-api.md). The key words MUST, SHOULD, and MAY are used as in RFC 2119.

## Model

```
Permission   declared in plugin.json and shown to the user ("ui", "account", …)
    ↓ required by
Capability   a named operation Venora performs ("mentions.showAvatar")
    ↓ called through
API method / event   venora.mentions.showAvatar(…), venora.on("mentions.added", …)
```

### Permissions

* A **permission** is consent. It tells the user what a plugin may cause Venora to do, and it is the unit the user agrees to.
* On its own, a permission grants nothing. There is no "storage" object a plugin receives.
* A permission matters only because capabilities and events require it.

### Capabilities

* A **capability** is the unit of enforcement. Each capability lists the permissions it needs, and a plugin MUST have declared **all** of them.
* The mapping is not one-to-one:
  * one permission can unlock many capabilities, for example `storage` unlocks settings and storage;
  * one capability can need several permissions, for example `mentions.showAvatar` needs `ui`, `account`, and `network`.

### Events

* Events list required permissions the same way.
* Subscribing needs all of them.
* Holding the permissions does not subscribe a plugin to anything.

### Fixed rules

* **Declared, not requested.** Permissions come from `plugin.json` and are fixed for each installed version. There are no runtime permission prompts and no optional permissions in version 1.
* **Changes need an update.** Changing a plugin's permissions requires installing a new version. The update goes through the same validation, and if it declares any sensitive permission the user sees the sensitive-permission warning again.
* **Checked on every call.** The plugin's declared permissions are bound to its runtime instance when it starts, and Venora checks them on every request. A capability the plugin is not entitled to fails with `permission_denied`, whatever payload was sent.
* **No exceptions for bundled plugins.** Plugins that ship with Venora run with only their declared permissions, like imported plugins.
  * **Consent differs.** Bundled plugins are not installed from a ZIP, so the user is never shown the sensitive-permission warning for them. Their permissions are fixed by the Venora release, and installing Venora is the consent. Today `mention-avatars` is the only bundled plugin with sensitive permissions (`account` and `network`). It is enabled by default but is not required, so the user can disable it on the Plugins page or in the toolbar popup. Its permissions are listed in its information dialog.
* **Unknown permissions block installation.** A plugin declaring an unknown permission is not installed, and Venora never ignores an unknown permission. A stored plugin whose permissions have become invalid is not started.

## Permission registry

The registry is `PLUGIN_PERMISSIONS` in `venora-chrome/permissions.js`. This table is checked against it by `tests/plugin-api-spec.test.js`.

| ID        | Name                 | Sensitive | What it lets the plugin cause                                                                                                | What it never gives the plugin                                                                                                                                        |
| --------- | -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage` | Storage              | No        | Reading its own settings, and storing its own data in `venora.storage`                                                       | Other plugins' settings or data; Venora's or Fermo's storage                                                                                                          |
| `ui`      | Interface changes    | No        | Notices, its declared CSS, mention avatars, commands on its own card, and the `mentions.added` and `commands.invoked` events | Direct DOM access; reading page content beyond what an event reports; any change to Venora's own dialogs, notices, or Plugins page; text written onto the page by CSS |
| `network` | Network access       | **Yes**   | Venora making web requests **on the plugin's behalf**, inside capabilities that require it                                   | Any way to send its own requests, or to see responses beyond what the capability returns                                                                              |
| `account` | Fermo account access | **Yes**   | Venora acting with the signed-in Fermo account **on the plugin's behalf**, inside capabilities that require it               | The session token, the account record, credentials, or profile data                                                                                                   |

Sensitive permissions are confirmed by the user, through a warning that lists them, before installation and before every update that declares them. A permission is sensitive if it lets a plugin cause Venora to:

* act on the user's behalf;
* send data off the device;
* use the user's identity.

In version 1, `network` and `account` are **consent markers** only:

* No capability performs arbitrary requests for a plugin.
* No capability returns account data.

They appear only where Venora itself uses the network or the account to carry out a narrow, fixed operation (for example, `mentions.showAvatar`). The registry description shown to the user MUST describe this accurately and MUST NOT suggest that the plugin receives the token.

## Permission → capability → API matrix

| Permission | Capabilities                                                                                                                           | Methods                                                     | Events                               | Other                          |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------ | ------------------------------ |
| *(none)*   | `events.subscribe`, `events.unsubscribe`, `test.echo`                                                                                  | `venora.on`                                                 |                                      |                                |
| `storage`  | `settings.get`, `storage.get`, `storage.set`, `storage.remove`, `storage.clear`, `test.permissionEcho`                                 | `venora.settings.get`, `venora.storage.*`                   | `settings.changed`                   |                                |
| `ui`       | `ui.toast`, `mentions.setAvatarSize`, `mentions.showAvatar` (with `account` and `network`), `commands.register`, `commands.unregister` | `venora.ui.toast`, `venora.mentions.*`, `venora.commands.*` | `mentions.added`, `commands.invoked` | The `css` file in the manifest |
| `network`  | `mentions.showAvatar` (with `ui` and `account`)                                                                                        | `venora.mentions.showAvatar`                                |                                      |                                |
| `account`  | `mentions.showAvatar` (with `ui` and `network`)                                                                                        | `venora.mentions.showAvatar`                                |                                      |                                |

The inputs, outputs, errors, and security boundaries of each capability are specified in [plugin-api.md §5](/plugin-api.md#5-capability-reference).

## Rules for contributors

* **Add a permission only when a capability needs it.**
  * Add the ID to `PLUGIN_PERMISSIONS` only when the same change adds a capability or event that requires it.
  * A permission that nothing uses gives users a false choice.
  * Venora checks at load that every capability and event names an existing permission.
* **Reuse before inventing.** Prefer an existing permission when its description already covers the new capability honestly. Add a new permission when users would reasonably want to refuse the new behaviour separately.
* **Mark it sensitive** if it meets the definition above.
* **Never make an existing capability or event stricter within an API version.** Adding a permission requirement to an existing capability or event is a breaking change ([plugin-api.md §9.4](/plugin-api.md#94-breaking-changes-which-need-a-new-api-version)).
* **Use the naming rules.** A permission ID is one lowercase word.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.getvenora.tech/plugin-api/plugin-permissions.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
