> ## Documentation Index
> Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> The capability catalog, the risk levels, and the install dialog flow.

A plugin can only do what its manifest declares and the operator
approves. The capability catalog is generated from one source of truth
(`capabilities.toml`) into the agent (Python and Rust) and the GCS
(TypeScript) so the three halves cannot drift. This page lists the real
catalog, the risk levels each capability carries, and how the install
dialog presents them.

There are 43 agent capabilities and 19 GCS capabilities. Three agent
capabilities are runtime-enforced (see the note in the agent section);
the GCS set is 12 UI slot registrations plus 7 data and command
capabilities.

## Risk levels

Every capability in the catalog carries a risk level. The install
dialog badges each requested capability by its level and surfaces an
overall risk for the plugin. The manifest also declares a top-level
`risk` field (`low`, `medium`, `high`, or `critical`).

| Level        | Meaning                                                                                           | Visual                       |
| ------------ | ------------------------------------------------------------------------------------------------- | ---------------------------- |
| **Low**      | Sandboxed or read-only. No flight or hardware effect.                                             | Plain badge.                 |
| **Medium**   | Touches shared hardware, opens the network, reads frames, or registers a sensor.                  | Yellow badge.                |
| **High**     | Can command the vehicle, inject into the estimator, drive output hardware, or spawn subprocesses. | Orange badge.                |
| **Critical** | Reserved as the top manifest-level band.                                                          | Red badge with warning icon. |

## Declaring permissions

Permissions go in the `agent.permissions` and `gcs.permissions` lists.
Each entry is an object with an `id` and an optional `required` flag:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
agent:
  permissions:
    - id: telemetry.read
      required: true
    - id: recording.write
      required: false
```

Required permissions are pinned on in the install dialog; the operator
cannot install while leaving them off. Optional permissions default to
off and the operator flips them on when wanted.

## Agent capabilities

43 capabilities, grouped by namespace. The risk column is the value
carried in the catalog.

<Note>
  Three agent capabilities are runtime-enforced at the IPC layer:
  `event.publish`, `event.subscribe`, and `hardware.gpio_out`. The host
  re-resolves the required capability from the method (and, for the event
  bus, from the topic) on every request and rejects an ungranted call.
  The other capabilities gate access at the surface they front (for
  example, a manager refuses to register a driver without the matching
  permission).
</Note>

### `event.*` (event bus)

| Capability        | Risk | Lets the plugin...                                       |
| ----------------- | ---- | -------------------------------------------------------- |
| `event.publish`   | Low  | Publish events on topics it has been granted (enforced). |
| `event.subscribe` | Low  | Receive events from granted topics (enforced).           |

### `mavlink.*` (flight controller link)

| Capability                     | Risk   | Lets the plugin...                                             |
| ------------------------------ | ------ | -------------------------------------------------------------- |
| `mavlink.read`                 | Low    | Observe the live MAVLink message stream.                       |
| `mavlink.write`                | High   | Inject MAVLink commands (mode, arm, param writes).             |
| `mavlink.tunnel`               | High   | Exchange application payloads over MAVLink TUNNEL frames.      |
| `mavlink.component.camera`     | Medium | Register as a MAVLink camera component.                        |
| `mavlink.component.gimbal`     | Medium | Register as a MAVLink gimbal component.                        |
| `mavlink.component.payload`    | Medium | Register as a MAVLink payload component.                       |
| `mavlink.component.peripheral` | Medium | Claim a generic MAVLink peripheral component id.               |
| `mavlink.component.vio`        | High   | Register as a visual-inertial-odometry source feeding the EKF. |

### Flight commands

| Capability               | Risk | Lets the plugin...                                        |
| ------------------------ | ---- | --------------------------------------------------------- |
| `vehicle.command`        | High | Send high-level commands (arm, takeoff, RTL, land, mode). |
| `flight.guided_setpoint` | High | Emit guided-mode position or velocity setpoints.          |
| `estimator.pose.inject`  | High | Push pose samples directly into the autopilot estimator.  |
| `mission.read`           | Low  | Read the active mission, fences, and rally points.        |
| `mission.write`          | High | Upload or modify missions, fences, and rally points.      |

### `telemetry.*`

| Capability         | Risk | Lets the plugin...                                      |
| ------------------ | ---- | ------------------------------------------------------- |
| `telemetry.read`   | Low  | Read the same telemetry feed the GCS consumes.          |
| `telemetry.extend` | Low  | Add new fields to the telemetry stream sent to the GCS. |

### `sensor.*.register`

| Capability                | Risk   | Lets the plugin...                                     |
| ------------------------- | ------ | ------------------------------------------------------ |
| `sensor.camera.register`  | Medium | Register a camera as a system sensor.                  |
| `sensor.depth.register`   | Medium | Register a depth or stereo sensor.                     |
| `sensor.lidar.register`   | Medium | Register a LiDAR.                                      |
| `sensor.imu.register`     | Medium | Register an auxiliary IMU.                             |
| `sensor.payload.register` | Medium | Register a payload device (sprayer, dropper, sampler). |

### `hardware.*`

| Capability            | Risk   | Lets the plugin...                                                   |
| --------------------- | ------ | -------------------------------------------------------------------- |
| `hardware.uart`       | Medium | Open UART serial ports.                                              |
| `hardware.i2c`        | Medium | Read and write I2C devices.                                          |
| `hardware.spi`        | Medium | Read and write SPI devices.                                          |
| `hardware.gpio`       | Medium | Read input and drive output GPIO pins.                               |
| `hardware.gpio_out`   | High   | Drive a GPIO output line or a bounded buzzer/LED pattern (enforced). |
| `hardware.usb`        | Medium | Claim raw USB devices for bulk transfers.                            |
| `hardware.usb.uvc`    | Medium | Read frames from USB UVC cameras.                                    |
| `hardware.camera.csi` | Medium | Read frames from MIPI CSI cameras.                                   |
| `hardware.audio`      | Medium | Access audio capture and playback devices.                           |

### `vision.*`

| Capability                   | Risk   | Lets the plugin...                                        |
| ---------------------------- | ------ | --------------------------------------------------------- |
| `vision.frame.read`          | Medium | Subscribe to normalized frames from the vision engine.    |
| `vision.model.register`      | Medium | Register an inference model with the vision engine.       |
| `vision.detection.publish`   | Low    | Publish detections (boxes, labels, track ids).            |
| `vision.detection.subscribe` | Low    | Receive detection batches plus the tracker's lock state.  |
| `vision.track.designate`     | Medium | Choose which object the single-object tracker locks onto. |

### Data, compute, and radio

| Capability          | Risk   | Lets the plugin...                                     |
| ------------------- | ------ | ------------------------------------------------------ |
| `network.outbound`  | Medium | Open outbound TCP, UDP, and HTTP connections.          |
| `recording.write`   | Low    | Write into the agent recording store.                  |
| `filesystem.host`   | Medium | Read and write files outside its own data dir.         |
| `process.spawn`     | High   | Launch subprocesses from its manifest spawn allowlist. |
| `radio.aux_stream`  | High   | Open an auxiliary stream on the radio link.            |
| `display.oled.page` | Low    | Contribute a page to the onboard display.              |
| `button.subscribe`  | Medium | Receive front-panel button press events.               |

## GCS capabilities

19 capabilities. The GCS half declares 12 UI slot registrations plus 7
data and command capabilities. UI slot capabilities mount a panel in a
named slot; the slot value itself goes in `contributes.panels[].slot`
(see the [Manifest reference](/developers/manifest)).

### UI slots

`ui.slot.node-detail-tab`, `ui.slot.cockpit-panel`, and
`ui.slot.flight-skill` are scoped to the currently selected node; the
other nine are fleet-level.

| Capability                     | Risk   |
| ------------------------------ | ------ |
| `ui.slot.fc-tab`               | Low    |
| `ui.slot.hardware-tab`         | Low    |
| `ui.slot.mission-template`     | Low    |
| `ui.slot.map-overlay`          | Low    |
| `ui.slot.video-overlay`        | Low    |
| `ui.slot.notification-channel` | Low    |
| `ui.slot.settings-section`     | Low    |
| `ui.slot.connection-protocol`  | Medium |
| `ui.slot.recording-processor`  | Low    |
| `ui.slot.flight-skill`         | Medium |
| `ui.slot.node-detail-tab`      | Low    |
| `ui.slot.cockpit-panel`        | Low    |

### Data and command

| Capability            | Risk   | Lets the plugin...                                      |
| --------------------- | ------ | ------------------------------------------------------- |
| `telemetry.subscribe` | Low    | Read live telemetry for paired drones.                  |
| `command.send`        | Medium | Send commands to a paired drone through the GCS bridge. |
| `recording.write`     | Low    | Save recordings to the GCS library.                     |
| `mission.read`        | Low    | Read mission plans loaded in the GCS.                   |
| `mission.write`       | High   | Upload, edit, or replace missions in the GCS planner.   |
| `cloud.read`          | Low    | Read shared fleet data from the cloud backend.          |
| `cloud.write`         | Medium | Write fleet data to the cloud backend.                  |

## Two-stage install

1. The operator drags a `.adosplug` into the install dialog.
2. The host parses the archive in memory: it validates the manifest,
   verifies the Ed25519 signature, and returns a summary with the
   requested permissions, the signer id, and the risk level. Nothing is
   written to disk.
3. The dialog renders the summary plus a permission grid. The operator
   flips optional toggles and clicks **Install**.
4. Only then does the host commit the install, unpacking the archive and
   writing state to disk.

A plugin that never makes it past step 3 leaves no traces.

## Re-prompt on update

Installing a newer version that requests one new optional permission
re-opens the dialog with only the new permission highlighted. Existing
grants are preserved. A new required permission is shown with emphasis
and the operator must approve it. Removing permissions in an update is
silent: the host drops the no-longer-declared grants on load.

## Capability tokens on the wire

Every plugin process runs with a capability token the supervisor mints
at start, bound to the plugin id, the granted capability set, a session
id, and an expiry. The agent IPC server checks the token and the
required capability before routing each request. The plugin cannot forge
a capability by lying in the envelope; the host re-resolves the required
capability from the method (and, for the event bus, from the topic) and
rejects an ungranted call with `permission_denied`.

## See also

* [Manifest reference](/developers/manifest)
* [Event hooks and bus](/developers/event-hooks-and-bus)
* [Lifecycle](/developers/lifecycle)
