Skip to main content

Module tenancy

Module tenancy 

Source
Expand description

Index ownership and expiry (paid-path plan S1, gap G2).

Before tenancy, any valid key could query any index_id: the handlers resolved <data_dir>/<id>.db straight from the URL and the caller’s identity was used only for metering. This module is the record that closes that: every index created through the API is owned by the key that created it, carries a created_at, and — when the operator configures a TTL — an expires_at after which it is refused.

The record lives in its own SQLite file in the data dir (tenancy.db), not inside each index’s database: codetopo-store owns the per-index schema (graph + audit chain), and ownership is a property of the service, not of one graph.

An index with no owner row is a legacy index — written before tenancy existed (or placed in the data dir by another tool, e.g. the CLI). Whether a legacy index is readable is decided by ownerless_readable:

  • the operator’s flag (CODETOPO_DENY_OWNERLESS_INDEXES) wins when set — 1/true denies legacy indexes to every key, 0/false keeps the original any-key rule;
  • unset, the default turns on how many tenants the deployment actually has: with more than one active key in the store a legacy index is denied (an upgraded self-hosted data dir that later gained tenants must not leak its pre-tenancy indexes across keys — fleet release gate F-5), and with one active key it stays readable, so the single-operator upgrade that created the legacy posture is never stranded by it.

A denied legacy index is answered exactly like a missing one (404 unknown_index), so the refusal cannot confirm it exists. The handlers enforce the rule; this module keeps the record and owns the decision.

Structs§

IndexRecord
One index’s ownership record.
Tenancy
The tenancy store: one SQLite connection, serialised behind a mutex.

Constants§

STORE_FILE_NAME
File name of the tenancy store inside the data dir.

Functions§

ownerless_readable
Whether an index with no ownership record (“legacy”) may be read by an authenticated key — the rule the module doc states, kept as one pure decision so both branches are testable without a server.