Skip to content

v0.3.0

Choose a tag to compare

@Mfrostbutter Mfrostbutter released this 28 Jun 11:55
· 137 commits to main since this release

Added

  • More AI providers for the assistant and workflow creation. Beyond OpenRouter / OpenAI / Anthropic / Ollama, the assistant now natively supports Perplexity, Groq, DeepSeek, Mistral, xAI (Grok), and Together AI, plus a Custom (OpenAI-compatible) provider: set a base URL in Models and point it at any OpenAI-compatible endpoint (Azure OpenAI, LiteLLM, vLLM, LocalAI, Fireworks, ...). They route through the shared OpenAI-compatible chat path with live model listing where the provider exposes a /models endpoint; Perplexity is offered tools-free since it rejects an unknown tools field. Each area (Code Lab / Error Triage / Assistant) still picks its own provider and model, and keys resolve from the Secrets store by convention ($PERPLEXITY_KEY, $GROQ_KEY, $DEEPSEEK_KEY, $MISTRAL_KEY, $XAI_KEY, $TOGETHER_KEY, $CUSTOM_LLM_KEY).

  • VPS deployment guide. A step-by-step walkthrough for hosting AgeniusDesk as a public web app on your own domain (DigitalOcean, Hostinger, or any Ubuntu VPS): provision, point DNS, run in Docker bound to localhost, and front it with Caddy for automatic HTTPS, plus a public-deployment hardening checklist. Ships docker-compose.prod.example.yml (Caddy reverse-proxy overlay) and Caddyfile.example so the all-Docker path is copy-paste. See docs/DEPLOY.md.

  • Community-module frontend isolation (sandboxed iframe). A community module's frontend view no longer runs in the app page. It loads in an <iframe sandbox="allow-scripts ..."> without allow-same-origin, so the module's code runs in an opaque origin and cannot read or change the host DOM, window, cookies, or storage: a buggy or hostile module can break itself but not the AgeniusDesk UI. The module reaches the host only through a postMessage bridge that reimplements window.AgeniusDesk (fetch, notify, navigate, openInHarness); the host verifies the message source and restricts fetch to same-origin /api/ paths (adding auth and CSRF host-side). The host also pushes the active theme's CSS variables into the frame and auto-resizes it to content height. Module code that already uses AgeniusDesk.* keeps working unchanged.

  • Community-module backend isolation (out-of-process, opt-in). A community module's backend can now run OUTSIDE the app process, selected in Settings > Modules (or the AGD_MODULE_ISOLATION env var, which overrides the setting). Two tiers:

    • Subprocess runs each module in a sandboxed child process: host backend imports are blocked, the env is scrubbed to an allowlist, and the host reaches it through a reverse proxy with a per-spawn secret.
    • Container runs each module in its own hardened Docker container (read-only rootfs, all Linux capabilities dropped, no-new-privileges, no Docker socket, pid/memory/cpu limits; modules that declare no network join an internal network with zero internet). This is the real OS boundary.

    Either way, privileged actions go through a loopback capability bridge, never direct host access: vault read/write scoped to the module's declared paths (checked against the symlink-resolved location), and a tool-free assistant.complete that runs the LLM host-side so the provider key never reaches the module. The default stays in-process, so existing installs are unchanged. The reference YouTube Research module is dual-mode: the same code runs in-process or isolated.

  • Fleet Health view. A dedicated view aggregating workflow health across every connected n8n instance: per-instance active/total workflows, error rate over recent executions, and the unhealthy workflows, plus a combined roll-up. Live parallel fan-out; a degraded or unreachable instance is shown, not fatal. The "one client becomes ten" pane.

  • Auto-install the error handler on connect. Adding an n8n instance now best-effort installs + activates the Global Error Handler workflow into it (idempotent), so its errors flow to AgeniusDesk from the moment it's connected. It posts to a container-reachable dashboard URL (AGD_PUBLIC_HOST, else a configured host alias). n8n's public API cannot set the instance-wide Error Workflow, so the connect result surfaces that one remaining manual step.

Fixed

  • Stored XSS in the shared error item (pre-release). The error renderer shared across Overview, Errors, and Fleet Health escaped an error's workflow_id / execution_id too weakly for the onclick / href contexts it writes them into. Since those fields arrive on the login-exempt error webhook, a crafted value could break out of the attribute and run script in the operator's dashboard. The component now escapes the attribute/JS delimiters (matching the source renderer) and percent-encodes ids in URLs; a node-driven regression test renders a hostile error and asserts no breakout.
  • Role floor on error operations. Error-store endpoints that reach into n8n (purge executions, install/activate the error handler) or clear stored errors now require the operator role, matching every other n8n-mutating route; reads and the machine webhook stay open.
  • Error handler vs. webhook token. The auto-installed Global Error Handler now sends the x-agd-webhook-token header (from $env.AGD_WEBHOOK_TOKEN), so error delivery keeps working when the dashboard requires a webhook token instead of silently dropping every error.

Next

  • Container tier hardening: drop the module worker to a non-root uid, and a per-host egress proxy that enforces the manifest's declared network.hosts (today a network-declaring module reaches any host).