# Permissions

Part of [Build a custom machine](https://www.ownbox.io/sdk/guide).

Deny by default. Each permission is one line under `permissions:`, and each line appears on the review card in the
words shown here. Lines marked † reach outside the Ownbox or change its records, and the card marks them for the
owner's attention.

| Permission | Asks for | Unlocks | The review card says |
|---|---|---|---|
| `think` | `{calls_per_month: N}`, or `true` | `m.think` | Ask your AI up to N times a month |
| `fetch` | `[host, ...]` | `m.fetch` to those hosts | Read *host* † |
| `keys` | `[{name, host, label}, ...]` | `m.fetch(..., key=)`, `m.spend` | Use your *label* on *host* † |
| `data` | `[people:read, ...]` | the people and conversation calls | one line per seam, below |
| `send` | `[{channel, per_day}, ...]` | `m.send_email`, `m.send_dm`, `m.reply_to_comment` | Send up to N emails (or DMs) a day † |
| `packages` | `[{name, version}, ...]` | `import` of those packages | listed under what it installs |

**`think`.** `true` grants 300 calls a month. `calls_per_month` is 1 to 5,000. `chars_per_month` (default 2,000,000,
at most 50,000,000) bounds the words the AI reads and writes for it. Past either, `m.think` is refused `over_budget`
until the month turns.

**`fetch`.** At most 20 hosts, each a public host name written exactly. An IP address is refused, as are private names
(`.local`, `.internal`, `.lan`, `.home`, `.test`, `.example`, `.onion` and the like) and the AI companies' own APIs: a
machine thinks through `m.think`, never with a key of its own.

**`keys`.** At most 10. `name` is lowercase letters, digits and `_`; `host` must also be under `fetch`; `label` (at
most 60 characters) is what the owner reads. Optional: `header` (default `Authorization`), `prefix` (at most 20
characters, like `"Bearer "`) and `help` (at most 200 characters, shown beside the key's field).

**`data`.** The seams, and the card's words for each:

| Seam | Unlocks | The review card says |
|---|---|---|
| `people:read` | `m.people_find`, `m.people_timeline` | Read the people your business has met |
| `people:write` | `m.person`, `m.touch` | Add people and note events on their timelines † |
| `conversations:read` | `m.messages`, `m.comments`, `m.conversation_for`, `m.follows_you` | Read your inbox's conversations |
| `conversations:write` | `m.claim`, `m.release` | Take conversations and give them back † |
| `reports:read` | nothing over the door yet | the seam's name, as written † |
| `settings:write` | nothing over the door yet | the seam's name, as written † |

**`send`.** `channel` is `email` (`m.send_email`) or `dm` (`m.send_dm` and `m.reply_to_comment`). `per_day` is 1 to
200.

**`packages`.** Only packages on the Ownbox's own list, at the list's exact version. The Ownbox installs them from its
own copies, checked against their hashes, into the machine's own environment. The list today: annotated-types,
beautifulsoup4, et-xmlfile, jinja2, lxml, markdown, markupsafe, numpy, openpyxl, orjson, pandas, pillow, pydantic,
pydantic-core, pypdf, python-dateutil, python-docx, pytz, pyyaml, six, soupsieve, tabulate, typing-extensions,
typing-inspection and tzdata. A package off the list is refused with the words to ask for it to be added. On your
computer, `ownbox run` runs a machine with Python's own library only, and says so.
