4.7 Choosing a storage backend and isolating mounts

So far, file and data mounts have used the node's defaults. That is the right starting point, but it helps to know what those defaults are — especially when one tenant has several mounts of the same kind.

The standard server defaults

  • A plain file mount uses the local filesystem under fileRoot.
  • A plain data mount uses the durable, file-backed store under dataRoot.
  • A plain query mount uses the reference query adapter over the tenant's data store.

The server scopes these stores by tenant. Restarting the node does not discard the default data store. If you want throwaway data, ask for it explicitly:

{ "path": "/scratch", "service": "data", "config": {
    "access": { "read": "A", "write": "A" },
    "store": { "adapter": "builtin:mem" }
} }

builtin:mem is ephemeral and shared inside the tenant; it ignores root, so it is useful for tests and scratch data, not for separating sensitive mounts.

Give security boundaries their own root

Mounts with no store block share their service kind's default store. That is convenient, but it means two data mounts can address the same dataset names. When a mount is a security boundary — for example, a public-write signup store beside the users dataset trusted by auth — give it a separate physical root:

{ "path": "/signups", "service": "data", "config": {
    "access": { "read": "A", "invoke": "all", "write": "A" },
    "store": { "adapter": "builtin:file", "root": ".rs2-signups" }
} }

For files, the equivalent is:

"store": { "adapter": "builtin:local", "root": ".rs2-site-assets" }

An explicit builtin:file or builtin:local adapter requires a safe, relative root. Absolute paths, drive letters, .., and an empty root are rejected when the tenant is built. This prevents two supposedly isolated mounts from silently landing on the same keys.

Built in, loadable, or operator-managed

store.adapter has three useful forms:

Form Use it for
builtin:file, builtin:mem, builtin:local, builtin:reference Backends compiled into the node
code:<name>@<version> A deployed JavaScript adapter for Redis, MongoDB, Postgres, S3, or another backend (8.9)
infra:<name> An operator-managed backend whose credentials stay outside tenant config (10.7)

The service above the backend does not change. A data mount still owns schema validation, PATCH, ETags, and discovery whether its records live in local files or MongoDB. Backend choice is infrastructure; the HTTP contract stays stable.

Part 5 now adds identity and access control to these stores.


Previous: 4.6 Listings, pagination, delete guard · Manual home · Next: Part 5 — 5.0 The security model →