D45. The author's AI reads reviews with a read-only key of its own; the session stays the author's (14 Oct 2026)
The app keeps the author’s session in the 0600 file of the local data (D43, as D40 does for the ElevenLabs key) so that the MCP server’s read tools reach the reviews. But the same file lets an agent run elabora publish or elabora review resolve: the rule « the AI reads, the author acts » (D43) then holds only by the agent’s instructions, not by what the credential can do. The hosting now gives a key that only reads (elabora-cloud C31, protocol 6).
- A key of the account, made and revoked with the session.
POST /v1/account/ai-keys { name }givesear_…once (kept as its SHA-256, with its name, creation and last use, listed with the account’s devices);DELETE /v1/account/ai-keys/<id>revokes it at once. It lists the account’s reviews, shows one and reads its comments with their anchors; every other route answers403 read-only-key(an allowlist on the hosting, so that a route added later is closed to it). Five keys an account, 60 requests a minute each; its use does not keep an abandoned account alive. - Its file, beside the session’s.
<local data>/credentials/elabora-ai-key(elabora-ai-key/1: the key, its id and name, the space, the API it belongs to; 0600 in a 0700 folder, written whole then moved;ELABORA_CLOUD_AI_KEY_FILEelsewhere for tests).@elabora/node/cloudcreateAiKey(name, { token?, forgetSessionFile? })makes one with the session given (the app’s) or the session file’s, keeps it there, and, asked, forgets the session file: what agents can reach on this computer then only reads.listAiKeys,revokeAiKey(which forgets the file when it held that key) and the command line’selabora account ai-key create [--name] [--replace-session] | list | revoke <id>do the rest. The key is in no return value and no output (ear_is masked like the other secrets).ELABORA_CLOUD_KEY_FILEmay hold one too, withELABORA_CLOUD_SPACE. - Reads take it first, everything else refuses it plainly. The MCP server’s
elabora_review_listandelabora_review_comments, and the command line’sreview listandreview comments, take the AI key before the session (connect(api, { readOnly: true })): an agent reads with the least it needs even where the author’s session is kept too. A command that acts (publish, review create, link, close, open, delete, reply, resolve, reopen, publication versions and withdraw, account handle) with only the key here stops before any request and says that it reads reviews only, that publishing, sharing a link, answering, resolving, closing and the account need the author’s session, and how to sign in (E_CLOUD_SESSION_REQUIRED); a403 read-only-keyfrom the hosting says the same. A revoked key is forgotten here and said (ai-key-ended); the MCP tools then tell the agent to ask the author for a new key or a sign-in, never for a code or a key itself. - A course’s reviews without the publications. The key cannot list publications, so each version of a review now names the course it was built from (
versions[].course, protocol 6):courseReviewsfinds a course’s reviews by it (with a session, by the publications as before too). - The app switches later (another session builds its side): it keeps the session in its own store (
setSessionStore, its safeStorage, D43 amended) and callscreateAiKeywith it; the credentials folder then holds the key and no session (forgetSessionFileremoves a session file left behind, whatever the store). Nothing in the app changes with this decision. - Rejected: the session in the keychain only (D43’s « the app’s decision »): the MCP tools would then need a sign-in from a terminal; a scope on the session itself (one token that sometimes may act would still be the author’s whole session in a file agents read); keys per agent with their own limits for publishing (D43’s « revisit if »: no agent publishes on its own yet). Revisit if: agents need to answer or resolve on their own (a write scope per key), or the app keeps the session in the keychain and the command line asks it for one.