Why
Today /mcp authenticates one token for the whole box, so it cannot tell whose turn it is
serving. This table is the fix described in one bot per user:
each bot gets its own token, and a token resolves to one person.
Shape
CREATE TABLE bot_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
token_hash TEXT NOT NULL UNIQUE, -- sha256 of the token; the token itself is shown once
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
label TEXT NOT NULL DEFAULT '', -- bot-totti786
created_at TEXT NOT NULL,
revoked_at TEXT NOT NULL DEFAULT '' -- empty = live
);
Semantics to hold to
- Hash at rest, show once. Same rule as sessions: a database dump must not be a set of working credentials.
revoked_at, not delete. Revocation should be visible in the record; a deleted row hides that a credential ever existed.- Cascade on user delete. Removing a person must remove their bot's token in the same statement, or a live profile keeps a live credential.
- Scope is the user's role, read at call time — not a snapshot in the token, so a role change takes effect without reissuing credentials.
Status
Not implemented. Until it is, chats.* tools are absent so the shared token cannot enumerate
conversations; see the decision.
Rendered from nx-master/data-model/bot_tokens.md · OKF bundle · regenerate with npm run render