Search

Search the documentation

Protobox

Managed Auth & Connections

Entities, hosted OAuth, GitHub App installs, and the connection lifecycle.

Protobox stores and refreshes credentials for you. Your job is to kick off the right flow for each end-user and let the platform host the callback. Credentials live server-side — the SDK never receives a token.

Entities: your end-users

An entity is one of your users, identified by a userId you choose (e.g. your own database id). Scope the SDK to an entity and every connection and tool call is isolated to that user:

const user = protobox.entity('user_123');

The userId is passed to the platform in-band (in the request body / execution context), never as a header. It maps to the platform's per-caller connection model.

Connection flows

Which method you call depends on how the integration authenticates (see integration.authTypes).

OAuth (most integrations)

const { authorizeUrl } = await user.connect('github');
// Redirect the user's browser to authorizeUrl. Protobox hosts the callback.
await user.waitUntilActive('github'); // poll until the credential is stored

connect() accepts options for advanced cases:

await user.connect('github', {
  provider: 'byok',              // use your own OAuth app instead of Protobox's managed one
  appCredentialsId: 'appcred_1', // which app credentials to use
});

GitHub App install

GitHub App integrations use an install flow instead of OAuth consent:

const { installUrl } = await user.install('github');
// Redirect the user to installUrl to install the app on their account/org.

Workspace-level API key

Some integrations authenticate with a static API key that belongs to your workspace (not a per-user account). Connect these at the workspace level:

await protobox.connections.connectApiKey({ integrationId: 'stripe', apiKey: process.env.STRIPE_KEY! });

Inspecting connections

// A specific user's connections
const conns = await user.listConnections();
// [{ id, integrationId, callerId, status, appCredentialsId, ... }]

// Workspace-level connections
const wsConns = await protobox.connections.list();

Connection lifecycle

A connection moves through these statuses:

StatusMeaning
pendingCreated; waiting for the user to finish the hosted flow.
activeCredential stored and auto-refreshed — tools are executable.
expiredCredential lapsed and could not be refreshed.
revokedDisconnected by you or the provider.

waitUntilActive(integrationId) polls a user's connections until the matching one is active, or throws TimeoutError (default 120s; configurable via { timeoutMs, intervalMs }).

Disconnecting

// A user's connection (needs the appCredentialsId from listConnections())
await user.disconnect('appcred_1');

// A workspace-level connection
await protobox.connections.disconnect('github');

Detecting "not connected" at execution time

If you execute a tool for a user who hasn't connected the integration, the result carries authRequired:

const result = await user.execute({ name: 'github.create_issue', arguments: { /* ... */ } });
if (result.authRequired) {
  const { authorizeUrl } = await user.connect('github'); // send them to connect
}

On this page