Permissions
Every plugin permission, what it allows, and how to evaluate risk.
Every plugin declares the permissions it needs in its manifest. taiku enforces these at runtime. If a plugin tries to call a bridge method it does not have permission for, the call is rejected. This is not advisory; it is enforced in the host bridge code.
Permission reference
| Permission | Risk | Description |
|---|---|---|
session.read | low | View session metadata, shells, and users. |
session.write | medium | Rename sessions and modify session metadata. |
terminal.read | low | Read buffered terminal output from shells. |
terminal.write | high | Send input to shells and create or close them. |
chat.read | low | Read session chat history. |
chat.write | medium | Send chat messages into the session. |
events.subscribe | low | Receive host-emitted plugin events. |
events.broadcast | medium | Broadcast custom events to other plugins and the session. |
ui.toolbar | low | Show a toolbar icon for the plugin. |
ui.toolbar.custom | low | Add custom toolbar actions, badges, and tooltips. |
ui.panel | low | Open and control sidebar, bottom, floating, tooltip, or overlay panels. |
ui.open | low | Open a path in the built-in file viewer. |
ui.toast | low | Show host toast notifications. |
ui.notify | medium | Send browser or desktop notifications. |
audio.play | medium | Play built-in sounds or plugin-provided audio URLs. |
tunnel.read | low | Read the session's published tunnel ports. |
workspace.read | low | Inspect workspaces, tabs, tiles, and layout state. |
workspace.write | medium | Create workspaces and modify the tile layout. |
hotkey.register | low | Register plugin-defined hotkeys. |
shell.alias | high | Expose shell alias commands inside terminals. |
kv.read | low | Read session-scoped shared plugin KV data. |
kv.write | medium | Write session-scoped shared plugin KV data. |
storage.read | low | Read plugin-owned persistent storage files. |
storage.write | medium | Write and delete plugin-owned persistent storage files. |
fs.list | low | List directories through the CLI-backed file API. |
fs.read.cwd | medium | Read files relative to the session working directory. |
fs.read | high | Read arbitrary files accessible to the session host. |
fs.write.cwd | medium | Write files relative to the session working directory. |
fs.write | high | Write arbitrary files accessible to the session host. |
agent.events | high | Read AI agent session history, events, and token usage. |
Risk levels
Low: the plugin can observe but not modify. Reading session metadata, subscribing to events, and displaying panels are low-risk because they do not change session state or access sensitive data.
Medium: the plugin can modify shared state or trigger visible side effects. Writing to session KV, sending chat messages, broadcasting events, and showing notifications all affect what other participants see or hear.
High: the plugin can take actions with real consequences. Writing to terminals means executing commands. Writing to the filesystem means modifying files. Reading arbitrary files means accessing anything the session host can access. These permissions should only be granted to plugins you trust completely.
Evaluating a plugin
When deciding whether to enable a plugin, look at its permission list and ask: does this plugin need these capabilities for what it claims to do?
A monitoring plugin like Event Log needs session.read and events.subscribe
and that makes sense. If it also requested terminal.write or fs.write, that
would be a red flag, because a read-only log viewer has no reason to write to
your terminals or files.
A command runner like Terminal Commander legitimately needs both terminal.read
and terminal.write, because its entire purpose is sending commands and viewing
output.
The general principle: fewer permissions means less risk. A plugin with only
ui.panel and events.subscribe can display information but cannot modify your
session. A plugin with terminal.write and fs.write can execute commands and
change files. Both are valid, but they represent very different trust levels.
Persistence scopes
Different permissions gate access to different storage layers:
| Storage layer | Gated by | Scope | Lifetime |
|---|---|---|---|
| Local secrets/settings | None (browser-only) | Current device | Until browser data cleared |
| Session KV | kv.read, kv.write | One session, all participants | Session lifetime |
| User KV | session.read | One user, all sessions | Persistent (Postgres) |
| Plugin file storage | storage.read, storage.write | One user + plugin | Persistent (server-side) |
| Session filesystem | fs.* permissions | Session working directory or full host | N/A (reads/writes host files) |