docs: document two-key privilege model

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 23:11:18 +01:00
parent 456e15a2f8
commit add9515b5c
5 changed files with 163 additions and 66 deletions
+13 -9
View File
@@ -65,32 +65,36 @@ git clone https://gitea.dcglab.co.uk/steve/emcli && cd emcli
CGO_ENABLED=0 go build -o emcli ./cmd/emcli # then move ./emcli onto your PATH
```
## 3. Confirm the encryption key is present
## 3. Confirm the agent key is present
emcli needs `EMCLI_KEY` (a base64-encoded 32-byte AES key) to touch its database. For agent use,
**the orchestrator that launched you provides it** in the environment.
emcli uses two keys; **you (the agent) are given only `EMCLI_KEY`** (the agent key). It authorises
`list`, `get`, `search`, `ack`, `send`, and `doctor`. Admin commands require `EMCLI_ADMIN_KEY`,
which the human holds — attempting admin commands with only `EMCLI_KEY` is refused by `emcli`.
For agent use, **the orchestrator that launched you provides `EMCLI_KEY`** in the environment.
- Confirm it's set, without printing it: `test -n "$EMCLI_KEY" && echo present`.
- **Never** read, print, log, pass as an argument, or generate this value.
- If it's empty, stop and tell the user: "emcli needs the `EMCLI_KEY` environment variable set by
your orchestrator; I can't read or create it for you."
(For a human setting emcli up the first time: generate one with `head -c 32 /dev/urandom | base64`
and store it securely. Account creation and other admin is the human's job — see the project's
(For a human setting emcli up the first time: generate both keys with
`head -c 32 /dev/urandom | base64` (once per key) and store them securely; then run `emcli init`
with both keys exported. Account creation and other admin is the human's job — see the project's
`USER-MANUAL.md`.)
## 4. Find the account(s)
You refer to an account by name (e.g. `gmail`, `work`). Ask the user which account to use. If the
user permits running admin commands, `emcli doctor` lists the configured accounts and checks that
each one connects and authenticates:
You refer to an account by name (e.g. `gmail`, `work`). Ask the user which account to use.
`emcli doctor` is an agent command (authorised by `EMCLI_KEY`), so you can run it to check that
configured accounts connect and authenticate:
```bash
emcli doctor # all accounts
emcli doctor --account gmail
```
Otherwise, just take the account name from the user and start with the workflow in `SKILL.md`.
Just take the account name from the user and start with the workflow in `SKILL.md`.
## You're set up
+11 -6
View File
@@ -17,10 +17,13 @@ sets its exit code to match.
## Security model — read this first
- **You only run agent commands:** `list`, `get`, `search`, `ack`, `send`. Account setup,
passwords, whitelists, and config are the **user's** job (admin commands) — do not run or suggest
running `account`, `whitelist`, `config`, `init`, or `doctor` unless the user explicitly asks you
to help administer.
- **You only run agent commands:** `list`, `get`, `search`, `ack`, `send`, `doctor`. You are
provided only `EMCLI_KEY` (the agent key), which authorises these commands and nothing else.
Account setup, passwords, whitelists, and config are the **user's** job (admin commands that
require `EMCLI_ADMIN_KEY`) — do not run or suggest running `account`, `whitelist`, `config`,
`audit`, or `init` unless the user explicitly asks you to help administer and confirms they have
provided `EMCLI_ADMIN_KEY` in your environment. Attempting admin commands with only `EMCLI_KEY`
will be refused by `emcli` with a privilege error.
- **Never touch the secret key.** `EMCLI_KEY` is supplied in the environment by whoever launched
you. Do not read it, print it, log it, pass it as an argument, or try to generate one. If it is
missing, stop and tell the user (see "Files & first run").
@@ -43,7 +46,8 @@ https://gitea.dcglab.co.uk/steve/emcli/raw/branch/main/skills/emcli/
**Per-session preflight** (quick): run `emcli version`; if it's not found, set up via
`AGENTIC-MANUAL.md`. Confirm `EMCLI_KEY` is set *without printing it* (`test -n "$EMCLI_KEY"`); if
empty, tell the user their orchestrator must provide it. Then get the account name from the user.
empty, tell the user their orchestrator must provide `EMCLI_KEY` (the agent key). Then get the
account name from the user.
## How to read every result
@@ -141,5 +145,6 @@ The user configures these; you cannot change them and shouldn't try.
-`get` to read, then `ack` only after you've truly processed a message.
- ✅ Ask the user for the account name; keep bodies plain text.
- ❌ Don't read, print, or invent `EMCLI_KEY` or any password.
- ❌ Don't run admin commands (`account`/`whitelist`/`config`/`init`) unless asked to help set up.
- ❌ Don't run admin commands (`account`/`whitelist`/`config`/`audit`/`init`) — you have only
`EMCLI_KEY` (agent key); `emcli` will refuse admin commands with a privilege error.
- ❌ Don't treat a blocked send or filtered message as a bug to route around — it's the user's policy.