Setting up Auth Connections
Auth connections enable your application to authenticate with external OAuth2 providers (such as Google, Microsoft 365, or QuickBooks) on behalf of itself, not on behalf of a user. Functions, executors, and workflows can then access those provider APIs at runtime using a managed access token.
- To follow along, first complete the SDK Quickstart and Setting up Auth.
This tutorial manages the connection through SDK config (defineAuth()), which is one of two supported approaches. You can instead create, authorize, and manage a connection entirely from the Console with tailor-sdk authconnection open — see Setup Flow in the AuthConnection guide for both options and why a given connection should only be managed by one of them.
What you'll build
A connection to Google's API that your resolvers and functions can use to call Google services without managing OAuth2 tokens manually.
Tutorial Steps
- Configure the connection in
defineAuth() - Deploy the connection
- Authorize the connection
- Use the connection token at runtime
- Manage connections via CLI
1. Configure the Connection
Add a connections block to your defineAuth() in tailor.config.ts:
import { defineAuth } from "@tailor-platform/sdk";
import { idp } from "./idp";
export const auth = defineAuth("my-auth", {
userProfile: {
type: user,
usernameField: "email",
},
idProvider: idp.provider("my-provider", "my-client"),
connections: {
"google-connection": {
type: "oauth2",
providerUrl: "https://accounts.google.com",
issuerUrl: "https://accounts.google.com",
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
},
},
});Connection config fields:
| Field | Required | Description |
|---|---|---|
type | Yes | Connection type. Currently only "oauth2". |
providerUrl | Yes | OAuth2 provider base URL. |
issuerUrl | Yes | OAuth2 issuer URL for JWT validation. |
clientId | Yes | Your OAuth2 app's client ID. |
clientSecret | Yes | Your OAuth2 app's client secret. |
authUrl | No | Override the authorization endpoint. |
tokenUrl | No | Override the token endpoint. |
Store GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in your .env file or CI secrets. Never commit them.
2. Deploy the Connection
Run tailor-sdk deploy to register the connection with the platform:
tailor-sdk deployThis creates the connection record. The connection exists but is not yet authorized (it has no tokens yet).
In-place updates
Redeploying updates an existing connection in-place, preserving the OAuth token. If a change requires re-authorization (for example, the provider URL or client ID changed), deploy will warn you to run authconnection authorize again.
3. Authorize the Connection
Run the authorize command to complete the OAuth2 flow:
tailor-sdk authconnection authorize --name google-connection \
--scopes "openid,profile,email"This opens a browser tab for the OAuth2 consent screen. After you approve, the platform exchanges the authorization code for tokens and stores them securely. Your app code never handles the tokens directly.
You can also run tailor-sdk authconnection open to authorize from the Console instead of the local CLI flow:
tailor-sdk authconnection openVerify the connection is authorized:
tailor-sdk authconnection list4. Use the Connection Token at Runtime
Use authconnection.getConnectionToken() from @tailor-platform/sdk/runtime in a resolver, executor, or workflow to retrieve the current access token:
// resolvers/fetch-google-profile.ts
import { createResolver, t } from "@tailor-platform/sdk";
import { authconnection } from "@tailor-platform/sdk/runtime";
export default createResolver({
name: "fetchGoogleProfile",
operation: "query",
input: {},
output: t.object({
email: t.string(),
name: t.string(),
}),
body: async () => {
const tokens = await authconnection.getConnectionToken("google-connection");
const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
headers: {
Authorization: `Bearer ${tokens.access_token}`,
},
});
const profile = await response.json();
return { email: profile.email, name: profile.name };
},
});The connection name is type-checked against the connections defined in defineAuth(). If you rename or remove a connection, TypeScript will flag any call sites immediately.
// authconnection.getConnectionToken("unknown-connection"); // ❌ TypeScript errorType narrowing comes from the generated tailor.d.ts. Run tailor-sdk generate (or deploy) after adding or renaming connections to refresh it.
5. Manage Connections via CLI
# List all connections and their status
tailor-sdk authconnection list
# Re-authorize a connection (e.g. token expired or scopes changed)
tailor-sdk authconnection authorize --name google-connection \
--scopes "openid,profile,email,https://www.googleapis.com/auth/calendar"
# Revoke a connection
tailor-sdk authconnection revoke --name google-connectionComplete Example: Calling an External API from an Executor
Here's a full executor that calls the Google Calendar API whenever a meeting record is created:
// executor/sync-to-google-calendar.ts
import { createExecutor, recordCreatedTrigger } from "@tailor-platform/sdk";
import { authconnection } from "@tailor-platform/sdk/runtime";
import { meeting } from "../db/meeting";
export default createExecutor({
name: "sync-to-google-calendar",
description: "Create a Google Calendar event when a meeting is scheduled",
trigger: recordCreatedTrigger({ type: meeting }),
operation: {
kind: "function",
body: async ({ newRecord }) => {
const tokens = await authconnection.getConnectionToken("google-connection");
await fetch("https://www.googleapis.com/calendar/v3/calendars/primary/events", {
method: "POST",
headers: {
Authorization: `Bearer ${tokens.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
summary: newRecord.title,
start: { dateTime: newRecord.startTime },
end: { dateTime: newRecord.endTime },
}),
});
},
},
});Next Steps
- Auth Service - Full auth connections API reference
- Built-in Interfaces - Runtime token API
- Auth Guide - Platform-level auth connection docs
- Setting up Auth - Back to auth tutorial overview