Skip to content

An app's account can belong to the team - #757

Draft
mxmzb wants to merge 60 commits into
mainfrom
shared-brokered-accounts
Draft

mxmzb wants to merge 60 commits into
mainfrom
shared-brokered-accounts

Conversation

@mxmzb

@mxmzb mxmzb commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

An app's account can belong to the team

An administrator can make a Composio app Shared: one account, connected once, that every Bot granted the app acts as. Until now every brokered app was personal — each person connected their own mailbox or tracker, and a Bot acting for the team had no account of its own to use.

What this adds

  • A Personal or Shared choice per app. An administrator switches an app on its admin page. The switch previews what it would end before it does anything, and nothing changes unless every account on the old side is withdrawn at the vendor first — a half-finished switch would leave people's mailboxes attached to an app that no longer reaches them.
  • Who may use it, approved per Bot. Owner only, named people and groups, or everyone, and separately whether email, Slack or webhook input may steer a run that uses the account. Checked on every call, against the app's answering row rather than whichever duplicate row was dialled.
  • Requests when it is too narrow. Publishing a Bot, assigning it a responsibility or adding a trigger tells the owner what an administrator still has to approve, and files the request. Administrators answer them in the Approvals inbox.
  • Writes ask first. Making an app Shared adds an ask-before-write rule over its tools, and removing the app or switching it back to Personal revokes that rule rather than leaving it standing over an account nobody holds.
  • A new brokered_connections table that records an account's holder — a person or the deployment — rather than assuming a person.

Before upgrading

  • Migration 0052_shared_brokered_accounts copies every Composio connection into brokered_connections and leaves composio_connections in place, unwritten. Rolling back to 0.1.2 works, but accounts connected after the upgrade are invisible to it.
  • A handoff now records what started the run it came from. Older remote Bots' signed runs carry no such record for up to ten minutes after the upgrade, and calls they make to a Shared app in that window are refused.

main is merged in as of bb29c63. It carried the AG-UI 1.0 upgrade, so a checkout of this branch needs bun install before it typechecks.

Verification

Check Result
bun run format clean
bun run lint clean
bun run typecheck 0 errors
Tests 6,357 pass, 0 fail

The suite was run in batches rather than as a single bun test. A whole-suite run exhausts PostgreSQL's 100-connection limit locally (sorry, too many clients already), because the suite now has 91 test files that each open a 2-connection pool, up from 62 on main. Every file passes; worth watching whether CI hits the same ceiling.

Still open

  • The live Composio check (bun run test:live-composio) has not been run. The test is written and gated behind describe.skipIf(!live), so it is inert without a key.
  • The admin flow has not been clicked through in a browser yet.

🤖 Generated with Claude Code

mxmzb and others added 30 commits October 7, 2026 20:02
Tests for the account holder, the audience check, the account-mode switch,
the shared-use inbox and the app screens. They fail until the code lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Personal or Shared mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anded-over work

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ccount row carry its own heading

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… account-holding app a mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… from a signed run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t it holds

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…request

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ounts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y its published display name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ccount's stored id

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l on them

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t through each Bot

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nistrators the requests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g for owners

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ming who acted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s for its shared apps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mxmzb and others added 30 commits October 7, 2026 20:59
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…audit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ployment's

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ount

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…red one on re-add

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urn them to the admin page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uded

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… to readers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… closed without a gate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd account holders

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, never a duplicate

A second mcp_servers row at the same composio:// address could mark a Shared
app Personal and let calls through it skip the audience gate, or let a
non-admin connect a personal account to it. Every account decision, the
gate, the audit's reachedAs and the mode write now resolve the app's
answering row, and the gate refuses if the mode changes before the call goes
out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Bot granted through a duplicate or non-canonical row of an app now gets the
approval the audience gate actually reads, appears once in what it holds, and
is found when the app's mode changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wering row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… is ended

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a duplicate row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fault

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e vendor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hared beside the empty state

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orget its rule on removal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o the running app

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… 37th positional argument

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e lint and format run

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two conflicts, both resolved by keeping each side:

- `CHANGELOG.md`: 0.1.1 and 0.1.2 were cut while this branch was open, so the
  Unreleased section this branch writes now sits above them rather than in
  their place. The migration note's rollback target moves from 0.1.0 to 0.1.2,
  which is the release somebody would actually roll back to.
- `server/src/app.ts`: an import-order collision only. Main's
  `createCoworkerRoutingService` import and this branch's shared-account
  imports landed in the same place; both are kept.

Main's AG-UI 1.0 upgrade changes `@ag-ui/core` out from under this branch, so
the merged tree needs `bun install` before it typechecks.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant