Menu

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 } gives ear_… 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 answers 403 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_FILE elsewhere for tests). @elabora/node/cloud createAiKey(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’s elabora 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_FILE may hold one too, with ELABORA_CLOUD_SPACE.
  • Reads take it first, everything else refuses it plainly. The MCP server’s elabora_review_list and elabora_review_comments, and the command line’s review list and review 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); a 403 read-only-key from 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): courseReviews finds 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 calls createAiKey with it; the credentials folder then holds the key and no session (forgetSessionFile removes 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.