Core Concepts
Workspaces
Section titled “Workspaces”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.
Providers
Section titled “Providers”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:
| Flag | Meaning |
|---|---|
auth_user | Supports user-level OAuth connections |
auth_installation | Supports app/bot installations (Slack, GitHub App) |
auth_api_key | Supports API key storage |
You can also create custom providers for internal services or unsupported OAuth providers.
Provider Configs
Section titled “Provider Configs”A provider config links your workspace to a provider. It stores:
client_idandclient_secret— your OAuth app’s identityscopes/bot_scopes— what to request during authorizationoauth_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 providerworkspace_template_values— for providers with per-tenant URLs (e.g., Zendesk subdomain)
One provider config per provider per workspace.
Installations
Section titled “Installations”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.
Connections
Section titled “Connections”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:
| Field | Description |
|---|---|
tenant_id | Which tenant owns this connection |
user_id | Which 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_id | The provider’s identifier for the authorizing user |
Attachment model
Section titled “Attachment model”The attachment field on a provider config determines how connections are scoped:
Tenant-attached ("tenant")
Section titled “Tenant-attached ("tenant")”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.
User-attached ("user")
Section titled “User-attached ("user")”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.
Credential resolution
Section titled “Credential resolution”getCredential is the universal entry point. It resolves across both connections and installations using the credential_for parameter:
| Value | Behavior |
|---|---|
"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.
Template variables
Section titled “Template variables”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_variablesincreateAuthSession. Stored in connection metadata for token refresh.
Events
Section titled “Events”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.
API Keys
Section titled “API Keys”Workspaces have two types of API keys:
| Role | Prefix | Access |
|---|---|---|
secret | sk_ | Full API access |
publishable | pk_ | Auth session creation only |
Use publishable keys in client-side code. Use secret keys server-side only.