Arcade 1.11.0
App version 5e1519c · released 2026-09-29 · previous 1.10.1
Release notes
This release removes the engine's chat completions API, changes the shape of every list response, turns a gateway built-in on by default, and changes five tool contracts. Read the Upgrade notes before upgrading. The first one blocks helm upgrade for any install with Redis TLS on; most of the rest are for the teams that call Arcade's APIs rather than for the cluster.
Database migrations
This release applies schema changes. Migrations run automatically on helm upgrade unless <service>.database.migrations is false.
- Engine — records when a credential renewal ended without a token. Required by the credential-renewal fix below.
- Engine — replaces the index behind the tool-execution listing with one that carries the tie-breaker, in two steps: create the new index, then drop the one it supersedes. Supports the list-ordering fix below; the listing is correct without it but sorts instead of reading the order from the index.
- Engine — adds a nullable column for MCP tool metadata to the tool catalog. Not required by anything else in this release, but the new engine reads and writes it, so it must apply before the new image serves.
- Engine — adds a table. Not required by anything in this release.
- Engine — adds three columns, with defaults, to an existing table. Not required by anything in this release.
- Coordinator and experience-api — none.
The index is built concurrently, so writes are not blocked, but the pre-upgrade migration hook waits for it: on a large execution history, allow for the build in your helm upgrade --timeout. Everything else is additive. Rolling back does not run down-migrations; the new columns and table stay, and the previous engine image's execution listing is served by the replacement index.
Security
GET /v1/tools/{name}andGET /v1/formatted_tools/{name}no longer return the full definition of a tool the access policy denies. They answer 404, as for an unregistered name. The read could be used to discover exactly what governance was meant to hide.- A tool the access policy refuses returns
400 tool_not_foundover REST, identical to an unregistered name. It previously ran the call and answered 200 with "access denied", which confirmed the tool existed. - A failed call to an unreachable server no longer returns the server's address. The same error carried the SSRF guard's refusals, so anyone able to register a worker could map internal reachability from tool-call errors. A worker response is also capped at 10 MB when it omits or understates its length.
- An engine restricted to a set of organizations can no longer start a tool-authorization flow for an organization outside that set.
- A malformed request URL no longer crashes the experience API — an unauthenticated denial of service.
- The worker no longer logs third-party request and response payloads. Libraries such as the GraphQL client logged full Linear responses — issue text, names, email addresses — and other toolkits logged URLs with their query strings. Third-party libraries now log at WARNING and above; Arcade's own worker logs are unchanged.
- The dashboard CSP drops
unsafe-inlineandunsafe-eval, and the experience API sends CSP,X-Frame-Options,Referrer-Policy,Permissions-Policyandnosniff. Both send HSTS. See Upgrade notes.
Resolved CVEs
Advisories remediated in the bundled application images since fd0f5f2:
- CVE-2026-45820 —
fflate0.8.3 in the dashboard - CVE-2026-56854 —
golang.org/x/crypto0.56.0 - CVE-2026-56855 —
golang.org/x/crypto0.56.0 - CVE-2026-78662 —
golang.org/x/crypto0.56.0 - CVE-2026-81870 —
go.opentelemetry.io/otel/sdk1.45.0 - CVE-2026-84378 —
httpx2/httpcore22.12.0 in the Mixpanel toolkit - CVE-2026-84381 —
httpx2/httpcore22.12.0 in the Mixpanel toolkit - GHSA-22p9-wv53-3rq4 —
linkify-it5.0.2 in the dashboard - GHSA-5p39-cfhj-2xmp —
anyio4.14.2 in the coordinator and across worker toolkits - GHSA-82r6-8w77-94w6 —
anyio4.14.2 in the coordinator and across worker toolkits - GHSA-866g-f22w-33x8 —
@ai-sdk/provider-utils4.0.51 in the experience API - GHSA-f38q-mgvj-vph7 —
protobufjs7.6.6 in the experience API - GHSA-gjv8-xp57-g29c —
soupsieve2.9.2 across worker toolkits - GHSA-j3f2-48v5-ccww —
protobufjs7.6.6 in the experience API - GHSA-j934-xhv5-fg8f —
soupsieve2.9.2 across worker toolkits - GHSA-v245-v573-v5vm —
linkify-it5.0.2 in the dashboard
Added
- Group-based tool access. A
group_accesscontextual-access plugin hides and refuses tools according to the caller's Okta, Entra ID or SailPoint ISC group membership, at both listing and execution. It is generally available with no feature switch: to stop enforcing it, set a configuration inactive or delete it. Created and edited from the dashboard or the plugins API. - Every MCP gateway URL is also a Registry page. Opened in a browser, the gateway URL shows a page for that gateway only: sign in (OAuth, or API key and user ID for a header-auth gateway), browse its tools grouped by app with how many you have authorized, run one, and — with suggestions on — see and back requests for tools that are missing. MCP clients are unaffected; the page is served only to browsers.
- Gateway suggestions. Adding
?registry_suggestions=trueto a gateway URL gives end users tools to file a request for a missing capability, browse existing requests and support one. Each is credited to the signed-in end user on every gateway auth type. Admins get a suggestions inbox on each gateway, with Open and Resolved tabs and an optional resolution note. 1.10.1 created the tables; this release reads and writes them. - A Browse tab on the Servers page adds a third-party MCP server from the shipped catalogue in one click, and shows each added server's authorization state on its tile.
coordinator.cspEnforce— the coordinator now sends a nonce-based Content-Security-Policy, Report-Only by default.trueenforces it.oauthProviders.providers[].oauth2— an override block applied over a well-known provider's bundled endpoints, scope delimiter and PKCE setting. This is how a Microsoft provider authorizes against a single Entra tenant; see Fixed.workerDefaults.telemetryOverrides— per-service telemetry for workers, shared by every worker. See Fixed.engine.gatewayBootstrap.waitForWorkers(defaulttrue), andtools_source: optimizedon a static gateway in the engine config, which builds its allowlist from every optimized tool in the worker catalogue at bootstrap, unioned with any explicittools:.- Gateway URL presentation options.
?tool_recommendation=falselists every configured tool instead of the recommendation surface, and?arcade_tools=falseleaves out the Arcade and System tools. The saved gateway is unchanged, and the options can only narrow what it allows. - Per-tool requirements on the public tools endpoint. Each tool carries its own OAuth provider with only that tool's scopes, and the secrets it reads. The toolkit-wide rollup on the catalog is unchanged.
- Audit Logs gets the standard table: page numbers with a total, a row detail you can link to, and a filter for an exact date range. Audit Logs and Tool Executions both show a Load newer banner when new rows arrive, without moving the table.
- New toolkits: Airtable (nine tools for bases and records, beside the existing starter), Calendly (twelve tools, beside the starter), Freshservice (six read-only tools with per-user OAuth; each customer registers their own Freshworks OAuth app) and Workday (time-off self-service).
- New tools in existing toolkits:
- Outlook Calendar:
UpdateEventchanges a meeting in place;RemoveEventFromMyCalendardrops your own copy without telling anyone;CancelEventcalls off a meeting you organize and tells the guests.GetEventreturnsbody_htmlandCreateEventtakesbody_format, so formatted descriptions survive a round trip. - Outlook Mail:
CreateMailFolder,MarkEmails(read state and the follow-up flag),MoveEmails, each with a shared-mailbox twin; replies takecc_add,cc_removeandbcc; messages reportsent_date_time. - Figma: eighteen tools for dev resources, comment triage, file metadata and versions, variables and library analytics.
- Firecrawl:
Search,ExtractData,GetExtractStatus,SearchDeveloperDocs,SearchResearchPapers,SearchGithubIssues. - Linear:
RemoveIssueRelation. - Google Calendar:
RespondToEventaccepts a tentative reply. - Google Slides:
GetSlideThumbnailcan return the image itself. - Google Docs: comments carry the passage they are anchored to and whether they are resolved.
- Zoom:
GetMeetingTranscriptreads the AI Companion transcript of a meeting that was not cloud-recorded.
- Outlook Calendar:
Changed
- Audit events go to the coordinator over HTTP. The engine used to write the audit stream directly; it now posts signed events to the coordinator, which owns the stream.
features.auditLog.publishMethod: redisrestores direct writes. System_ManageAuthorizationis on by default. See Upgrade notes.- A tool call over REST answers the way MCP does. A policy refusal is
400 tool_not_found; a403for an unauthorized user keeps its status and error name and adds anauthorizationobject (url,id,provider_id,scopes); and executing a tool that needs authorization now starts the authorization flow, as MCP already did. - List endpoints honour the requested window. Connected accounts applied the offset twice and skipped rows on every page after the first; secrets ignored
limit/offset; a worker's tool list came back unsorted in an undocumented shape and now returns documented tool responses, sorted and paged; execution, gateway and plugin listings break timestamp ties by id so rows cannot swap between pages. - The coordinator logs one structured line per request. Each carries
request_id, method, path, status and duration, so a Datadog filter on onerequest_idfinally returns coordinator lines. The chart passes--no-access-logso uvicorn's own access line is not written twice. Query strings are never logged. The coordinator and engine also continue arequest_idthat arrives only in W3C Baggage instead of minting a new one. - The engine reads
engine.yamlonce, at startup. It used to reload in place whenever the mounted ConfigMap changed, so during ahelm upgradeold pods could switch to the new config one at a time before being replaced. The chart already rolls engine pods on a config change; a hand-edited ConfigMap now takes effect on the next restart. - Tool-access refusals are recorded in the execution history for calls over MCP and the
Arcade.*built-ins, where they previously left no trace. A refusal because the policy could not be consulted has its own reason. Expect more failed rows on projects with an access policy. - Gateway bootstrap waits for workers and refuses to empty the gateway list. Only with
engine.gatewayBootstrap.enabled: true. The bootstrap Job waits for the incoming release's workers before running, and a bootstrap that cannot resolve its allowlist now fails instead of reconciling to no static gateways at all. - Google file-picker links are 14 to 21 percent shorter across every Google Workspace toolkit, so an agent that writes one out is less likely to break it, and the picker page now confirms which files were shared.
Fixed
- Unread audit events are no longer silently discarded. The engine trimmed the audit stream at 10,000 entries while the coordinator allowed 100,000, so a lagging consumer lost events it had not read. Both writers now trim at
features.auditLog.streamMaxLen. - One refused credential renewal no longer stalls a whole tenant. Callers waiting behind the renewal lease were never told the provider had refused it, so each waited out its own 60-second deadline and received no tools. Tool listing checks every provider in the tenant, so one dead credential stalled
Arcade_ListApps,Arcade_SelectToolsand the MCP handshake for everyone. Waiters now learn the outcome within milliseconds. Requires the engine migration. - Minute-long
POST /v1/tools/selectstalls. Tool listing resolved authorization for every tool in the organization and then filtered, so one unrenewable credential anywhere stalled the response. Authorization is now resolved over the filtered list, and access hooks are asked only about the gateway's own tools rather than the whole catalogue. - Remote MCP authorization:
- An operator's scope selection reaches the authorization link. Opening the servers list left a scope-less request behind that answered the next click, which a server requiring a scope refused for an hour.
- An operator who holds a personal credential for a server can authorize that server once it holds none, instead of being told it is already authorized.
- An OAuth server's tools appear in the gateway picker as soon as it is authorized, rather than after someone opened its details page.
- A server that accepts
initializeanonymously and challenges only on a tool call, such as AWS's managed MCP server, is reported as needing authorization instead of permanently requirement-free. - A server that rejects the legacy
pingis no longer reported unhealthy.
- A worker keeps its tools when its catalog cannot be read. An unreachable third-party MCP server used to have its whole catalog deleted until the next successful sync. A worker whose first fetch fails no longer vanishes from the admin API.
- Tool results arrive as the tool wrote them. An upstream MCP server's
contentis forwarded beside itsstructuredContentrather than replaced by the JSON of it, and multi-block, scalar and string results are no longer escaped a second time. - Listing workers no longer fails in a project with none — the case on an install with no default workers configured.
- The engine's calls to the coordinator bypass
HTTP_PROXY/HTTPS_PROXY. The in-cluster service hostname did not match typicalNO_PROXYentries, so API-key verification went through a corporate proxy and failed. - A tenant-scoped
oauth2block on a well-known provider is honoured again. Since 1.9.x a Microsoft provider configured for a single Entra tenant authorized against the multi-tenant authority, which a single-tenant app registration refuses. Set it throughoauthProviders.providers[].oauth2. - A JWT
expclaim mapped toexpires_inin a custom OAuth provider no longer fails token exchange and refresh. - Expired execution history is marked for deletion at :00 and :30 rather than 30 minutes after each engine start, so frequent restarts no longer postpone retention for hours.
- Worker traces on Helm installs. The chart never passed
telemetry.*to the worker, so worker spans were missing even withtelemetry.traces: otlp. Worker pods now restart when telemetry values change. - With tool discovery enabled (
discovery.enabled), an engine replica recovers by itself after a discovery pod is evicted instead of failing every recommendation until restarted, and a lookup that failed reaches the agent as a retryable error rather than an empty list or an unknown tool. - The dashboard recovers after a deploy. A tab open across a deploy that asked for a removed file showed an error panel nothing could clear; it now reloads once onto the current build. Screens that swap a button label no longer crash with a page-translation extension running.
- Clearing the retention-days box on the Logging Policy page no longer refills it — deleting the 7 to type a 4 saved 74.
- New users are no longer skipped past onboarding's goal picker because of an instance-wide static gateway.
- The published engine OpenAPI documents plugin and hook routes at the paths that exist, under
/v1/orgs/{org_id}/…and/v1/orgs/{org_id}/projects/{project_id}/…. - Toolkits:
- Notion: every call returned 401 — the Authorization header lacked the
Bearerscheme. - Slack: tools taking
channel_nameresolved it by paging the workspace's most limited API on every call, so a few agents could rate-limit every Slack tool in a workspace. Private channels are no longer labelled public. - Gmail:
ForwardEmailquotes the original's HTML and stays in its thread. - Google Calendar:
CreateEventhonourssend_notifications_to_attendees; guests were emailed whatever was asked. - Google Drive:
SearchFilesfinds the contents of shared-drive folders and holdslimitto Drive's range. - Figma: version history pages toward older versions.
- Outlook Mail: multi-line replies keep their line breaks; a subject containing a line break or null is refused rather than silently altered.
- PagerDuty:
GetTeamreturns members, services and schedules, which it always reported empty. It and a few user tools declare the scopes their requests need, so users may be asked to authorize again. - Zoom: meeting search no longer steers transcript requests to recorded meetings only, and lists every standing one-to-one.
- Linear: project lookups by name work again. See Upgrade notes.
- Notion: every call returned 401 — the Authorization header lacked the
Removed
POST /v1/chat/completions, its project-scoped twin,/v1/admin/models, the chart'sllm:block andengine.llmSsrfAllowlist.page_countandcountfrom list responses.- Cursor pagination on the audit-log listing:
cursor,next_cursor,has_more. - The scheduled-execution runner.
- The
ArcadeEngineApistarter toolkit. - Outlook Mail's
MoveEmailToFolderandSharedMailboxMoveEmailToFolder. - Outlook Calendar's
online_meeting_urlandWhoAmIdefault_timezone. - Firecrawl 3.x arguments listed in Upgrade notes.
Operator impact
redis.tls.insecureSkipVerifyis required whenredis.tls.enabledis true; the chart will not render without it.- New values, all defaulting off or to the previous behaviour except the first two:
engine.manageAuthorization.*(on),features.auditLog.publishMethod(http; was effectivelyredis),coordinator.cspEnforce,oauthProviders.providers[].oauth2,workerDefaults.telemetryOverrides,engine.gatewayBootstrap.waitForWorkers. - Removed value:
engine.llmSsrfAllowlist. manage_authorization:inengine.extraConfigstops the render.- Coordinator access logs change format; update any parser keyed on uvicorn's access line.
- A hand-edited engine ConfigMap no longer takes effect without a pod restart.
- Worker Deployments gain a telemetry ConfigMap and restart when telemetry values change.
- The dashboard and experience API send HSTS with
includeSubDomains. - Engine migrations: one required, one index rebuild sized by the execution history, three with nothing depending on them.
- Integrators must migrate off chat completions,
page_count/count, audit-log cursors and single-request secret listings; Outlook Mail, Outlook Calendar, Figma, Linear and Firecrawl callers must migrate.
API & behavior
POST /v1/chat/completions(both paths) and/v1/admin/models: 404.- Every list response: exactly
items,limit,offset,total_count. - Audit-log listing:
limit/offsetonly;cursorignored. GET /v1/admin/secrets: default page of 100. User sources: default 100, max 500.GET /v1/workers/{id}/tools: documented tool responses withqualified_name, sorted and paged.GET /v1/tools/{name},GET /v1/formatted_tools/{name}: 404 for a policy-denied tool;Arcade.*built-ins now resolve.POST /v1/tools/execute: policy refusal is400 tool_not_found;403carriesauthorization; the call starts the authorization flow.POST /v1/tools/searchandPOST /v1/tools/selectare in the published OpenAPI spec, so generated SDKs expose them.- The public tools endpoint: per-tool
requirements. - Gateway URLs:
?tool_recommendation=false,?arcade_tools=false,?registry_suggestions=true. - Gateway suggestions: list, create and resolve under
/v1/orgs/{org_id}/projects/{project_id}/gateways/{gateway_id}/suggestions. - MCP tool results: upstream
contentforwarded besidestructuredContent; no second escaping. - Sessionful MCP no longer puts the engine's internal error text in a JSON-RPC error's
data, matching the stateless transport. - Tool-call errors for an unreachable server name only the toolkit and tool.
System_ManageAuthorizationlisted on gateways by default.