Notarizing documentation
Threat model
Developer preview. Not yet production ready. This page is rendered from docs/threat-model.md of the Notarizing repository at revision d23579e737f9d1e16e07b3c6b21a51282d64027e. It describes the behavior of that revision.
Contents
This page states what notarizing protects, from whom, and where its protection ends. It ends
with a hardening checklist for operators. It describes this revision. The security
assumptions are declared in
declarations.md
(ASM-LOOPBACK-LOCAL-USER, ASM-BROWSER-SAMESITE, ASM-KA2A-PRINCIPAL). Report a
vulnerability as SECURITY.md says.
Assets
| Asset | Where it is |
|---|---|
| Imported source text, check reports and artifacts | workspace.db in the workspace directory |
| Review records and their attribution | workspace.db |
| Control token | control.token in the workspace while serve runs |
| Viewer secret | viewer.token in the workspace and standard error of serve |
| Browser session cookie and CSRF token | The browser of the operator |
| ka2a signing key, broker client key and SASL password | Files that the adapter configuration names |
| Backups, bundles and exports | Files that the operator writes |
Trust boundaries
- Operator account. Notarizing trusts the operating-system account that owns the workspace. Every process of that account can read the workspace and the token files.
- Browser. The browser reaches
serveon loopback. A viewer can read. A reviewer can append review records within an expiring grant. Neither can import, purge, change policy or bindings, configure a provider or write to a repository. - CLI control. The CLI sends administrative operations to
servewith the bearer token ofcontrol.token. The token never goes to the browser or to MCP. - MCP client.
notarizing mcpreads the whole workspace through read-only tools on standard input and output. It has no tool that writes. - ka2a principal. A producer is identified by a verified ka2a signature and a source binding of the adapter configuration. The binding, not the request, selects its source namespace, operations and repositories.
- Imported content. Repository files, reports, artifacts and review text are untrusted data.
Threats that notarizing handles
| Threat | Control |
|---|---|
A web page in the browser sends requests to serve (CSRF, DNS rebinding) | Exact Host and Origin checks, Sec-Fetch-Site, a CSRF token on every POST, SameSite=Strict cookie, no CORS, a strict Content-Security-Policy. |
| Guessing the viewer secret | 256-bit secret, rotated after each use, at most 5 failed attempts per minute. |
| A reviewer escalates to administrative operations | The browser API has no administrative route. A grant has a scope and a time to live of 1 minute to 8 hours. |
| Imported text tries to run code or fetch a URL | Notarizing never executes imported content and never fetches a URL from it. git runs with every transport protocol off. Text output replaces control and bidi characters; the browser renders text only. |
| Imported text tries to instruct an agent (prompt injection) | MCP tools are read-only and bounded to 512 KiB. Each response marks the text as untrusted data. The worst result inside notarizing is a misleading answer, not a change. |
| A report claims a pass that it did not earn | Reported and evaluated status stay separate. Only reviewed bindings and the assessment policy create coverage. A reported pass is not an established pass. |
| A ka2a producer submits for another source | Signatures verify against the trusted catalog. The source binding selects the namespace. Broker TLS, optional mutual TLS, SASL and certificate revocation lists protect the connection. |
| Two processes write the workspace | One owner at a time, enforced by a lock. Other commands go through the control API. |
Threats that notarizing does not handle
- Other processes of the same account. They can read
workspace.db,control.tokenandviewer.token, and act as viewer, reviewer or operator (ASM-LOOPBACK-LOCAL-USER). - Other accounts on a shared host. They can connect to the loopback ports. They need a secret to do anything, and the secrets are in files with mode 0600. An administrator (root) can read everything.
- Other local web services. Browsers send the session cookie to every port of
127.0.0.1. A local service on another port that the browser visits receives the cookie and can replay it. The grant time to live limits the damage. - Data at rest.
workspace.db, backups and bundles are not encrypted. Anyone who can read the files can read the content. - Agents. Notarizing cannot stop an agent from following instructions in the text that it reads, or from sending that text to a hosted model or to its other tools.
- Malware on the host, a compromised browser or browser extensions with page access.
- Purged content in copies. A purge does not reach backups, bundles, exports or file system snapshots that exist already.
- Denial of service by the operator account. A local process can fill the disk or stop
serve.
Hardening checklist
Workspace and files:
- [ ] Run notarizing under a dedicated operating-system account, or under your own account on a single-user host. Do not share the workspace account with other people.
- [ ] Keep the workspace directory at mode 0700 and its files at 0600.
notarizing doctorwarns about other modes and owners. - [ ] Put the workspace and the backups on an encrypted file system if the content is confidential. Notarizing does not encrypt them.
- [ ] Keep backups in a directory that only the workspace account can read.
backupcreates the directory with mode 0700. Keep the mode when you copy or rotate backups. - [ ] Delete or purge old backups and bundles when the content must go. See Back up and restore.
Browser and serve:
- [ ] Keep
serveon loopback. Do not put it behind a proxy that changes theHostorOriginheader. - [ ] To use the browser from another computer, use an SSH tunnel to the same port number
and open
http://127.0.0.1:<port>. The server refuseslocalhostand other host names. - [ ] Use a browser profile for notarizing that visits no other local web service.
- [ ] Give review grants with the narrowest scope and the shortest time to live that the task needs. Revoke a grant when the review ends.
- [ ] Stop
servewhen you do not use it. A stop ends every session and grant.
Agents:
- [ ] Give an agent the MCP server only if the agent may read the whole workspace.
- [ ] Configure the agent to treat tool results as data, not as instructions.
- [ ] Check where the agent sends tool results, for example a hosted model.
Optional ka2a adapter:
- [ ] Use the
qualifieddurability profile and TLS.allow_plaintextis for development only. - [ ] Use mutual TLS or SASL SCRAM, and give the notarizing principal only the broker ACLs
that
ka2a topics acl-planprints (see the operator guide). - [ ] Set
tls.crl_fileand replace the lists before their next update.notarizing doctorwarns when the update is due. - [ ] Keep the signing key, the client key and the password file at mode 0600.
- [ ] Give each producer one source binding with only the operations and repositories that it needs.
Dependencies:
- [ ] Run
make vulncheckbefore you build a release. See docs/release.md.