v1.7.0 — per-user areas, email, calendar & webhooks
Added
- Per-user service/skill areas + per-user cron (act-as). Tenancy extends from private data to shared capabilities and scheduled jobs.
policy.jsonusers gainservices/skills=all|none| allow-list of names/categories — default-deny and fail-closed under enforcement. A cron job can run as an owner: a non-admin schedules only as themselves, an admin as anyone.cron_duemints a short-lived per-job capability token (HMAC, HKDF-derived fromSTORAGE_ENCRYPTION_KEY, 5-min TTL, single-use); the runner presents it viaact_as_begin/act_as_end, so it holds no standing authority and a job is scoped to its owner at the owner's own privilege. Seedocs/per-user-areas.md. - IMAP — read incoming email.
imap_add/imap_list/imap_search/imap_fetch— the read-side counterpart to SMTP. Read-only (BODY.PEEK) so nothing is marked seen; attachments optionally saved to/data/work. SSRF-guarded connect, vault password. - CalDAV — calendars as data.
caldav_add/caldav_list_calendars/caldav_list_events/caldav_add_event— discover calendars, list events in a range, create an event (over PROPFIND / REPORT / PUT, no extra dependency). SSRF-guarded, TLS verified by default, vault password. - Webhooks — inbound + outbound. Inbound: a public
POST /hooks/<name>route (via FastMCPcustom_route, outside the MCP OAuth) lets external services push events into the inbox — making the brain event-driven. Each hook authenticates with a per-hook shared secret token and/or HMAC signature (constant-time), rejects unknown/unsigned requests, caps body size, and only deposits into the inbox — never the tool surface. Outbound:webhook_send(url, json_body)— a thin SSRF-guarded POST. Operator note: expose only/hooks/*past the reverse proxy's auth, never/mcp. - Running version is observable — logged at startup, returned by
ping, and shown in thebootstrapcatalog header.
Changed (breaking)
- Isolation now rides on
AUTH_ENFORCE. The separateTENANCY_ISOLATEswitch is retired — one switch, "enforce means enforce". WithAUTH_ENFORCE=1(the default), non-admins are confined (own memory scope + private vault) and default-denied services/skills until an admin grants them; homelab mode (AUTH_ENFORCE=0) is unchanged. A leftoverTENANCY_ISOLATE=1in.envbecomes a harmless no-op. Admins are unaffected.
Upgrade
cd <deploy-dir> && git pull && docker compose pull && docker compose up -d --force-recreateThen ping reports AICortex v1.7.0. For inbound webhooks, pass only /hooks/* past the reverse proxy's auth (never /mcp). To run per-user cron jobs, the NAS runner wraps each job in act_as_begin / act_as_end. You can drop a leftover TENANCY_ISOLATE=1 from .env.
Full diff: v1.6.3...v1.7.0