Skip to main content
Composio

Composio's tool/auth aggregation → the Naive /connections primitive

Composio gives an AI agent authenticated access to 1,000+ third-party apps through one API — create an auth config, send the user through a hosted OAuth link, then composio.tools.execute("GITHUB_CREATE_ISSUE", …). It does that job well, and the API is clean. But it is also a separate vendor account:
  • Tool connections live behind their own API key, dashboard, and user_id (entity) namespace.
  • That user_id scopes connected accounts and nothing else — it knows the agent’s Slack and GitHub grants, but not its virtual card, its inbox, its vault secrets, or its KYC status.
  • “Who let this agent post to Slack, and what else can it touch?” is answered in Composio for tools, and somewhere else for everything else. There is no shared accountability.
Naive’s /connections primitive gives the agent the same capability — connect an app, list its tools, execute them — but rooted in one identity:
  • The tenant user that holds the connections is the same user that owns its cards, its email inbox, its vault secrets, and its KYC.
  • What the agent is allowed to connect and execute is decided by that user’s Account Kit at execution time — not by which tools you remembered to pass into the model.
  • Every connect and execute lands in the same per-user activity log as everything else the agent does.
This guide maps Composio’s API to Naive’s, shows the smallest working swap, and is explicit about what does not map yet.
Composio is a trademark of its owner, used here for identification only. No endorsement or affiliation is implied.
Tested against: Composio TypeScript SDK @composio/core v3 (API surface per docs.composio.dev, snapshot June 2026) and the Naive Node SDK @usenaive-sdk/server against the Naive API (base https://api.usenaive.ai/v1, docs snapshot June 2026).Version notes:
  • Composio v3 renamed v1/v2 concepts: entity → user, action → tool, app → toolkit, integration → auth config, connection → connected account. This guide uses v3 terms.
  • For Composio-managed OAuth, connectedAccounts.initiate() is being retired (org cutover by 2026-07-03) in favor of connectedAccounts.link() — same return shape and redirectUrl. This guide uses link().
  • Both are evolving APIs — verify method names against your installed SDK version.

Concept map

Before / after: the core path

The path that matters for almost every agent is connect an app, then execute one of its tools. Here it is on both platforms (GitHub used as the example toolkit).
The execute call lines up almost one to one. The real differences to plan for:
  • No auth-config resource. Composio makes you create an auth config (ac_…) per toolkit before linking. Naive connects by toolkit slug directly using managed auth — there is no intermediate object to create or track. White-label OAuth (your own client id/secret) is set on the Account Kit (connections_config.custom_auth_configs), not as a standalone resource.
  • Arguments are the last positional arg. Composio takes { userId, arguments }; Naive’s scoped client already knows the user, so execute(toolkit, tool, args) passes the tool’s arguments directly.
  • The user id is your identity, not a separate entity. In Composio user_id is an entity that exists only for tool auth. In Naive the same id is a tenant user that also owns the agent’s cards, inbox, vault, and KYC.

Connecting an app (OAuth)

Both platforms return a hosted redirect URL and surface a connection status you can poll.
  • On Naive, connecting a service is a sensitive action and may be approval-gated by the Account Kit — connect can return pending_approval (202) until a human approves.
  • INITIATED rows older than ~10s are reconciled from the provider before responding. See Connection status.

Minimal viable migration

The smallest swap that keeps a working agent running is just connect + execute. You do not need to recreate auth configs, tenant-user fan-out, or Account Kits to make your first call.
1

Install the SDK and set your key

Set NAIVE_API_KEY (a server-side key from the dashboard).
2

Map your user ids

Composio’s user_id (entity) becomes a Naive tenant user. Reuse your own database id as external_id so the mapping is 1:1, or pass it straight into naive.forUser(id) if you already key by it.
3

Drop the auth-config step, connect by slug

Replace authConfigs.create + connectedAccounts.link(userId, authConfigId, …) with a single client.connections.connect(toolkit, { callbackUrl }). Same hosted redirectUrl.
4

Swap execute

Replace composio.tools.execute(tool, { userId, arguments }) with client.connections.execute(toolkit, tool, args). Tool slugs (GITHUB_CREATE_ISSUE, GMAIL_SEND_EMAIL, …) are unchanged.
5

Ship it

At this point you are off Composio for the core connect/execute path. Everything below is upside, not a requirement.

Consolidate further once you’re on Naive

This is where the migration pays for itself. In Composio, user_id isolates tool connections and nothing else. On Naive, the unit of isolation is a tenant user, and it isolates the agent’s entire footprint.

Gain #1 — one identity across primitives

  • With Composio, the agent’s connections are an island. With Naive, naive.forUser(acme.id) is a single handle to connections and cards and email and vault and KYC.
  • You provision a customer’s whole agent footprint from one identity, and tear it down from one place. Sibling tenants can never read each other’s connections, cards, or secrets.

Gain #2 — execution-time permission enforcement

  • Which apps an agent may connect, and which tools it may run, is policy on the Account Kit — not a check you hand-write, and not just “which tools you passed to the model.”
  • The agent’s code is identical for every tier — client.connections.execute("github", …). Whether the call runs is decided by the caller’s kit at execution time:
    • A blocklist/allowlist mode governs which toolkits connect at all.
    • Per-tool enable/disable filters lock execution down to specific tools.
    • approvalToolkits (or requiresApproval) freezes a sensitive call until a human approves — the API replays it only after approval.
  • Move the user to a kit that drops github and the exact same line returns forbidden, with no code change on your side. Composio gates auth (which accounts exist); Naive additionally gates execution per user.

Gain #3 — unified accountability

  • Every connect, execute, and disconnect for a customer lands in one per-user activity log — alongside their card, email, and vault events, not in a separate tools dashboard:
  • That is the question that is hard to answer when tool auth lives in Composio, cards live in Stripe, and secrets live somewhere else. Under Naive it is a single query.

What does not map yet

A migration guide that hides gaps is worse than none. None of the following block the core path (connect → list tools → execute → disconnect all map cleanly), but they are real differences. Check this list against your app before you commit.
If your agent depends on Composio triggers, per-framework provider toolsets, or pinned toolkit versions, those are the gaps most likely to matter. The connect-then-execute loop with Account-Kit governance — the most common agent tool-auth pattern — maps cleanly today.

Where to go next