Skip to content

Security

Please report vulnerabilities privately, through GitHub’s Report a vulnerability button on this repository (Security → Advisories), not in a public issue. You will get an answer within a week. Include the version, how to reproduce it and what an attacker gains.

Datanotes is an engine that reads and writes a folder of Markdown notes (the vault). It is meant to run on your own machine, for you and the agents you choose.

  • The HTTP server listens on 127.0.0.1 unless told otherwise (--host). It answers no CORS preflight, so web pages cannot call it.
  • Only GET / answers without a token (status and version).
  • To reach it from outside (a phone, a hosted assistant), publish it through a reverse proxy or a tunnel, over HTTPS, and give each device or agent its own app token. Publish the MCP server (datanotes-mcp serve) the same way: it holds no credentials and passes each agent’s token on.
Credential Where What it can do
Owner token httpServerToken in the settings Everything: data, schema, apps, webhooks, undo. Keep it on the machine.
App token created with POST /datanotes/apps/create/ (owner only), stored hashed Read everything; write only the tables in its write patterns; change the schema only with ddl. It cannot create webhooks, manage apps or undo; with maintain it may also undo, restore, vacuum, configure and rebuild the semantic index (an agent’s own token).

Prefer an app token per device or agent: it has only the permissions it needs and the journal names it. MCP clients use the same tokens: the MCP server passes them to the engine.

Every write is journaled with its actor. The agent’s name, model and session come from the client and are self-reported; the credential (auth: owner or app, and the app’s name) is set by the server and cannot be claimed.

Every path is resolved inside the vault: a path with .., a backslash, a drive letter or a NUL is refused, both by the engine’s operations and by the file host. Symbolic links inside the vault are followed: do not link to folders you would not give the engine.

Nothing leaves the machine unless you turn it on:

  • Semantic search sends note text to the embedding provider you configure (semanticEnabled, off by default; provider semanticProvider / semanticBaseUrl). A local provider (Ollama, LM Studio) keeps it on the machine.
  • Telemetry sends logs to the OTLP endpoint you configure (telemetryEnabled, off by default): operations, routes, note paths, actors, tool names and error messages (which may quote a value), not note bodies. telemetryHeaders (e.g. an ingestion key) is stored in the settings file; OTEL_EXPORTER_OTLP_HEADERS keeps it out.
  • Webhooks (created by the owner) post change events to the URLs they name.
  • Apps’ MCP endpoints (registered by the owner): the engine sends each app’s mcp_token, and the arguments and caller of every call of its tools, to the app’s mcp_url, which may be remote.
  • Git sync (--git-sync) pushes the vault to its git remote.