Skip to content

Core Concepts

A workspace is the root isolation boundary. Every entity (provider configs, installations, connections, API keys, events) is scoped to a workspace. Workspaces have an encryption key for credential storage and a tier that determines rate limits.

The provider catalog contains 221+ pre-configured OAuth providers (Slack, GitHub, Google, Shopify, etc.) with authorization URLs, token endpoints, health checks, and webhook configs. Providers are global — not workspace-scoped.

Each provider declares which credential types it supports:

FlagMeaning
auth_userSupports user-level OAuth connections
auth_installationSupports app/bot installations (Slack, GitHub App)
auth_api_keySupports API key storage

You can also create custom providers for internal services or unsupported OAuth providers.

A provider config links your workspace to a provider. It stores:

  • client_id and client_secret — your OAuth app’s identity
  • scopes / bot_scopes — what to request during authorization
  • oauth_redirect_url — Authpipe’s callback URL (registered with the provider)
  • attachment"tenant" or "user" (see Attachment Model)
  • signing_key — for verifying inbound webhooks from the provider
  • workspace_template_values — for providers with per-tenant URLs (e.g., Zendesk subdomain)

One provider config per provider per workspace.

An installation represents an app-level credential. Think: a Slack bot installed in a customer’s workspace, or a GitHub App installed on an organization.

Installations belong to a provider config and are scoped to a tenant_id. They hold bot/app tokens that are separate from user tokens.

Statuses: active, needs_reauth, suspended, deleted.

A connection represents a user-level credential — an individual OAuth grant, a stored API key, or a webhook secret.

Connections belong to a provider config and optionally to an installation. They are always scoped to a tenant_id and optionally a user_id depending on the attachment model.

Key fields:

FieldDescription
tenant_idWhich tenant owns this connection
user_idWhich user within the tenant (user-attached only)
attachment"tenant" or "user" — inherited from provider config
credential_type"oauth_token", "api_key", or "webhook_secret"
status"active", "needs_reauth", "failed", "revoked"
external_user_idThe provider’s identifier for the authorizing user

The attachment field on a provider config determines how connections are scoped:

One connection per tenant. The credential belongs to the org, not a specific user. If a different user re-authorizes the same tenant, the existing connection is updated (upsert).

Use when: The credential is shared — e.g., a Frame.io project token for the whole company.

Lookup: tenant_id only. user_id is accepted but ignored for resolution.

One connection per user within a tenant. Each user has their own credential.

Use when: The credential is personal — e.g., Google Calendar for each team member.

Lookup: tenant_id + user_id.

getCredential is the universal entry point. It resolves across both connections and installations using the credential_for parameter:

ValueBehavior
"any" (default)Try connection first, fall back to installation
"installation"Only return installation-level credential
"user"Only return user-level connection credential
getCredential({ provider: "slack", tenantId: "org_acme" })
→ tries connection → none found
→ tries installation → returns bot token (source: "installation")
getCredential({ provider: "slack", tenantId: "org_acme", credentialFor: "user" })
→ tries connection → none found
→ fails (no fallback to installation)

The response includes source ("connection" or "installation") so you always know where the credential came from.

Some providers have per-tenant URLs (e.g., {shop}.myshopify.com, {subdomain}.zendesk.com). Template variables are resolved at two scopes:

  • Workspace-scoped — Set in the provider config’s workspace_template_values. Applied to authorization URLs, token URLs, and health check URLs.
  • Connection-scoped — Passed per-request via template_variables in createAuthSession. Stored in connection metadata for token refresh.

All credential mutations emit events: connection.created, connection.refreshed, connection.failed, connection.revoked, installation.created, credential.stored, webhook.received, etc.

Events are delivered to your webhook URL with HMAC-SHA256 signature verification.

Workspaces have two types of API keys:

RolePrefixAccess
secretsk_Full API access
publishablepk_Auth session creation only

Use publishable keys in client-side code. Use secret keys server-side only.