Both are stored server-side as the same kind of record: a per-user key with a per-tool allowlist (scopes). Every guarantee below applies to both equally.
Identity model
- A credential belongs to exactly one user in one tenant/workspace. Every tool call executes as that user.
- Reads are filtered server-side to the user’s visibility: tenant → workspace → department memberships → user layer. A Member and an Admin calling the same tool can legitimately get different row counts.
- If the user is deactivated or moved to another tenant, the credential stops working immediately.
Roles
Role gates are enforced per tool call, server-side — having a tool on your allowlist does not bypass its role gate.
OAuth 2.1 connect flow
The connector flow is standard OAuth 2.1: Authorization Code + PKCE (S256), public clients via Dynamic Client Registration. Discovery documents live at/.well-known/oauth-protected-resource and the authorization-server metadata endpoint; MCP clients handle all of this automatically.
Key behaviors:
- Consent screen shows whether the requested scope set is read-only or includes write/management tools.
- Access tokens are keys. Each issued token is a per-user key row with the same per-tool scopes, audit log and revocation as a manual API key.
- Token TTL is 30 days. Auth codes are single-use and expire after 10 minutes.
- Redirect URIs must be
https://(plushttp://localhost/http://127.0.0.1for local development).
First connect: full tool surface
On a genuine first connect, the token receives the full first-party tool surface — all reads and writes (router meta-tools excluded, see Conventions), plus:- per-table data write grants (
insert_<table>/update_<table>) for every registered data table in your tenant, and - the federated vertical tools your account already has (e.g.
vertical__vertical_card).
Reconnect: scopes are inherited
Reconnecting the same user + same connector does not reset scopes. The new token:- Inherits the scope set of the prior active key for that user+connector — including a deliberately reduced (e.g. read-only) set. Writes are never silently re-added.
- Unions in the read-only baseline: read-only tools shipped after your first connect are auto-added on reconnect, so your surface never goes stale. Write tools are never auto-added.
- Deactivates the prior token for that user+connector — reconnects never accumulate active keys.
Per-tool toggles
In the app (Settings → MCP Access) every key/connector has a per-tool on/off matrix. A tool switched off is recorded as an explicit opt-out (denied_scopes) on manual keys, so the auto-add baseline never re-enables it behind your back. Tools not on the allowlist are rejected with a clear error (see the error table in Conventions).
What never travels the API
- Secrets. No tool returns or accepts passwords, credentials, OAuth secrets or vault contents.
user_createsends an invite link by email instead of returning a password; third-party integrations (Composio) are connected in the app UI only; agent credential assignments (allowed_credentials) are app-only. - Cross-tenant data. There is no tool that reads another tenant.
Audit
Everytools/call is logged (tool name, status ok | error | denied, duration, row count, argument keys — never values). Denied calls are audited before rate-limiting is applied.