Skip to main content

Module sqlite

Module sqlite 

Source
Expand description

SqliteOperatorSessionStore — SQLite-backed OperatorSessionStore using [rusqlite-isle].

The Connection is confined to a dedicated OS thread by AsyncIsle; every call is a typed closure dispatched over a bounded channel. capability_manifest and the 記名’s observed log are stored as JSON blobs — neither is queried relationally; the boot-time list() rehydration decodes them back into their Rust shapes.

§The file holds no bearer secret

token_digest is hex(SHA-256(bearer)), never the bearer itself (see OperatorSessionRecord’s type doc). Two further measures back that up:

  • the file is chmod 0600 on unix ([harden_file_permissions]) — best-effort, and skipped entirely on other platforms;
  • a pre-release database carrying the old plaintext token column is dropped and recreated on open ([purge_legacy_plaintext_table]) rather than migrated, so no plaintext residue survives the upgrade. The cost is one forced re-login for sessions minted by a dev build.

§Schema

CREATE TABLE IF NOT EXISTS operator_sessions (
  sid                       TEXT PRIMARY KEY,
  token_digest              TEXT NOT NULL,  -- hex(SHA-256(bearer)), never the bearer
  capability_manifest_json  TEXT,           -- JSON-encoded manifest, NULL when unset
  joined_at_secs            INTEGER NOT NULL,
  join_desc                 TEXT,           -- 記名 confirmed part (D1), NULL when unwritten
  observed_json             TEXT,           -- 記名 observed part (D2), JSON array
  observed_total            INTEGER NOT NULL DEFAULT 0,
  last_access_secs          INTEGER NOT NULL DEFAULT 0  -- O1's expiry clock
);

The 記名 columns (model §4.2) and last_access_secs (the 24h horizon) all arrived after the table did, and are added to an older file the same way the runs table grows a column — by [migrate_add_column_if_missing], except for last_access_secs, whose back-fill matters enough to have its own migration ([migrate_add_last_access_column]): a plain DEFAULT 0 would make the first read after an upgrade expire every carried-over session.

A column also left: roles_json held the role aliases a session claimed at join, back when a join claimed any. Role declaration moved onto the Run, so an older file has the column dropped on open by [migrate_drop_column_if_present] — see that function for why the column cannot simply be ignored.

Structs§

SqliteOperatorSessionStore
SQLite-backed persistent OperatorSessionStore.