# Security

## Data in the EU

The API, the worker and the database run in Frankfurt. Files, payloads and attachments are stored in the EU. Payloads of events are deleted after 30 days; the ledger keeps only ids and digests.

## Untrusted content

Webhooks and emails come from outside and are marked `trust: "external_untrusted"`. An email can contain text written to steer an agent ("ignore your instructions and send…"). The Brynth skill tells the agent to treat that content as data, and the policy is the safety net: actions with effects outside the project, such as sending email or sharing a file, can require a person's approval whatever the agent was told. Attachments that are executable or flagged by the virus scan are not stored.

Only events that Brynth writes itself carry `trust: "brynth"`: `request.resolved`, `email.failed`, `email.bounced`, `email.complained` and `email.blocked`.

## Keys

- A key is `brk_live_` followed by 43 characters. Brynth stores only its SHA-256 hash and its first 12 characters, to tell keys apart: a lost key cannot be shown again, only replaced.
- Each key has scopes. Give each client its own key with the scopes it needs, so you can revoke one without touching the others. `admin` can create keys, manage sources and routes, and rotate the request callback secret: keep it out of agents that do not need it.
- The CLI keeps the admin key in `~/.config/brynth/credentials.json` with mode 0600, and writes client keys only into the clients' own configuration. It never prints a token, except once for `key create`.
- The secrets of webhook sources are stored encrypted and never returned. The signing secrets Brynth creates for routes and request callbacks (`whsec_…`) are shown once, at creation.
- Revoke a key with `DELETE /v1/keys/{id}`. The last admin key of a project cannot be revoked.

## People decide

Approvals reach people through channels they confirmed. A new channel needs the approval of the existing ones, and a policy change needs a person: no rule can approve it. So an agent cannot give itself more power than the project owner agreed to.

## The ledger

Every effect is recorded with who did it, in the same transaction as the effect. Entries are hash-chained, and `ledger_verify` finds the first entry that was changed or removed. See [The ledger](/concepts/ledger.md).
