Auth
Auth is a service for configuring authentication and authorization in your Tailor Platform application.
Overview
Auth provides:
- User profile mapping to TailorDB types
- Machine users for service-to-service authentication
- OAuth 2.0 client configuration
- Identity provider integration
For the official Tailor Platform documentation, see Auth Guide.
Configuration
Configure Auth service using defineAuth():
Definition Rules:
- One auth per application: Each application can have exactly one Auth service
- Configuration location: Define in
tailor.config.tsusingdefineAuth()and reference directly in the config'sauthfield
import { defineAuth } from "@tailor-platform/sdk";
import { user } from "./tailordb/user";
const auth = defineAuth("my-auth", {
userProfile: {
type: user,
usernameField: "email",
attributes: { role: true },
},
// Optional when you don't define userProfile:
// machineUserAttributes: {
// role: t.string(),
// },
machineUsers: {
"admin-machine-user": {
attributes: { role: "ADMIN" },
},
},
oauth2Clients: {
"my-oauth2-client": {
redirectURIs: ["https://example.com/callback"],
grantTypes: ["authorization_code", "refresh_token"],
},
},
idProvider: idp.provider("my-provider", "my-client"),
});
export default defineConfig({
auth,
});User Profile
Maps authenticated identities to a TailorDB type:
userProfile: {
type: user, // TailorDB type for user records
usernameField: "email", // Field used as username (must be unique)
attributes: {
role: true, // Enable 'role' as a user attribute
},
},Example TailorDB type for user profile:
// tailordb/user.ts
import { db } from "@tailor-platform/sdk";
export const user = db.type("User", {
email: db.string().unique(), // usernameField must have unique constraint
role: db.enum(["admin", "user"]),
...db.fields.timestamps(),
});type: The TailorDB type that stores user records.
usernameField: The field in the TailorDB type used as the username. This field must have a unique constraint (.unique()) since it is used to uniquely identify users.
attributes: Specifies which fields from the TailorDB type are used as user attributes. Set to true to enable a field. Enabled attributes must be assigned values in all machine user definitions. Only fields with ValueOperand types (string, boolean, string[], boolean[]) can be used as attributes. The id field and datetime/date/time types are excluded.
Attribute List
In addition to attributes (key-value map), you can configure attributeList to expose UUID-type fields as an ordered list. This is useful for referencing related records by their IDs.
userProfile: {
type: user,
usernameField: "email",
attributes: { role: true },
attributeList: ["organizationId", "teamId"],
},attributeList: An array of field names from the TailorDB type. These fields will be exposed as an ordered list of UUIDs. Only UUID-type fields (non-array) can be included in the attribute list.
Example TailorDB type with UUID fields for attribute list:
// tailordb/user.ts
import { db } from "@tailor-platform/sdk";
export const user = db.type("User", {
email: db.string().unique(),
role: db.enum(["admin", "user"]),
organizationId: db.uuid(), // Can be used in attributeList
teamId: db.uuid(), // Can be used in attributeList
...db.fields.timestamps(),
});The attributeList values are accessible via user.attributeList as a tuple:
// In a resolver
body: (context) => {
const [organizationId, teamId] = context.user.attributeList;
},
// In TailorDB hooks
.hooks({
field: {
create: ({ user }) => user.attributeList[0], // First UUID from list
},
})Machine User Attributes (without userProfile)
When you want to use machine users without defining a userProfile, define machineUserAttributes instead. These attributes are used for:
- type-safe
machineUsers[*].attributes context.user.attributestyping (viauser-defined.d.ts)
import { defineAuth, t } from "@tailor-platform/sdk";
export const auth = defineAuth("my-auth", {
machineUserAttributes: {
role: t.string(),
isActive: t.bool(),
tags: t.string({ array: true }),
},
machineUsers: {
"admin-machine-user": {
attributes: { role: "ADMIN", isActive: true, tags: ["root"] },
},
},
});To update types in user-defined.d.ts, run:
tailor-sdk generateMachine Users
Service accounts for automated access without user interaction:
machineUsers: {
"admin-machine-user": {
attributes: { role: "ADMIN" },
},
"readonly-machine-user": {
attributes: { role: "READER" },
},
},attributes: Values for attributes enabled in userProfile.attributes (or all fields defined in machineUserAttributes when userProfile is omitted). All enabled fields must be set here. These values are accessible via user.attributes:
// In a resolver
body: (context) => {
const role = context.user.attributes?.role;
},attributeList: Values for fields enabled in userProfile.attributeList. Must be an array of valid UUIDs in the same order as declared in userProfile:
// userProfile with attributeList
userProfile: {
type: user,
usernameField: "email",
attributes: { role: true },
attributeList: ["organizationId", "teamId"],
},
machineUsers: {
"admin-machine-user": {
attributes: { role: "ADMIN" },
attributeList: [
"550e8400-e29b-41d4-a716-446655440000",
"7c9e6679-7425-40de-944b-e07fc1f90ae7",
],
},
},These values are accessible via user.attributeList:
// In a resolver
body: (context) => {
const [organizationId, teamId] = context.user.attributeList;
},
// In TailorDB hooks
.hooks({
field: {
create: ({ user }) => user.attributes?.role === "ADMIN" ? "default" : null,
},
})
// In TailorDB validate
.validate({
field: [
({ user }) => user.attributes?.role === "ADMIN",
"Only admins can set this field",
],
})Machine users are useful for:
- CI/CD pipelines
- Background jobs
- Service-to-service communication
- E2E testing
Get a machine user token using the CLI:
tailor-sdk machineuser token <name>Using auth.invoker()
The auth.invoker() method creates a type-safe reference to a machine user for use in workflow triggers. This specifies which machine user's permissions should be used when executing the workflow.
// tailor.config.ts
export const auth = defineAuth("my-auth", {
machineUsers: {
"admin-machine-user": {
attributes: { role: "ADMIN" },
},
},
// ... other config
});// resolvers/trigger-workflow.ts
import { createResolver, t } from "@tailor-platform/sdk";
import { auth } from "../tailor.config";
import myWorkflow from "../workflows/my-workflow";
export default createResolver({
name: "triggerMyWorkflow",
operation: "mutation",
input: {
id: t.string(),
},
body: async ({ input }) => {
// Trigger workflow with machine user permissions
const workflowRunId = await myWorkflow.trigger(
{ id: input.id },
{ authInvoker: auth.invoker("admin-machine-user") },
);
return { workflowRunId };
},
output: t.object({
workflowRunId: t.string(),
}),
});The invoker() method is type-safe and only accepts machine user names defined in the auth configuration.
OAuth 2.0 Clients
Configure OAuth 2.0 clients for third-party applications:
oauth2Clients: {
"my-oauth2-client": {
redirectURIs: [
"https://example.com/callback",
`${website.url}/callback`, // Type-safe URL from StaticWebsite
],
description: "My OAuth2 client",
grantTypes: ["authorization_code", "refresh_token"],
accessTokenLifetimeSeconds: 3600, // 1 hour
refreshTokenLifetimeSeconds: 604800, // 7 days
requireDpop: true, // Require DPoP for this client
},
},redirectURIs: Allowed redirect URIs after authentication.
description: Optional description of the client.
grantTypes: Supported OAuth 2.0 grant types:
authorization_code- Standard OAuth 2.0 authorization code flowrefresh_token- Allow refreshing access tokens
accessTokenLifetimeSeconds: Optional access token lifetime in seconds. Minimum: 60 seconds, Maximum: 86400 seconds (1 day). If not specified, uses platform default.
refreshTokenLifetimeSeconds: Optional refresh token lifetime in seconds. Minimum: 60 seconds, Maximum: 604800 seconds (7 days). If not specified, uses platform default.
requireDpop: Optional boolean to require DPoP (Demonstrating Proof of Possession) for this client. When set to true, the client must use DPoP tokens for authentication. If not specified, DPoP is not required.
Get OAuth2 client credentials using the CLI:
tailor-sdk oauth2client get <name>Identity Provider
Connect to an external identity provider:
idProvider: idp.provider("my-provider", "my-client"),See IdP for configuring identity providers.
CLI Commands
Manage Auth resources using the CLI:
# List machine users
tailor-sdk machineuser list
# Get machine user token
tailor-sdk machineuser token <name>
# List OAuth2 clients
tailor-sdk oauth2client list
# Get OAuth2 client credentials
tailor-sdk oauth2client get <name>See Auth Resource Commands for full documentation.
SDK vs Platform Naming
Note for Platform developers: The SDK uses different names than the underlying Platform API for user attributes:
SDK Platform API Description attributesattribute_mapKey-value map of user attributes attributeListattributesOrdered list of UUID values This mapping is handled automatically by the SDK. If you're reading Platform documentation or API responses, be aware of this naming difference.