IdP (Identity Provider)
IdP is a built-in identity provider service for managing user authentication.
Overview
The Built-in IdP provides:
- User registration and authentication
- OAuth client management
- Integration with Auth service
For the official Tailor Platform documentation, see Identity Provider Setup.
Configuration
Configure the Built-in IdP using defineIdp():
Definition Rules:
- Multiple IdPs allowed: You can define multiple IdP instances in your config file
- Configuration location: Define in
tailor.config.tsand add to theidparray - Uniqueness: IdP names must be unique across all IdP instances
import { defineIdp, defineConfig } from "@tailor-platform/sdk";
const idp = defineIdp("my-idp", {
clients: ["my-client"],
permission: {
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
update: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
sendPasswordResetEmail: [{ conditions: [], permit: false }],
},
});
// You can define multiple IdPs
const anotherIdp = defineIdp("another-idp", {
clients: ["another-client"],
permission: {
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
update: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
sendPasswordResetEmail: [{ conditions: [], permit: false }],
},
});
export default defineConfig({
idp: [idp, anotherIdp], // Add all IdPs to the array
});Options
permission
Per-operation permission policies for IdP user management. Controls who can create, read, update, delete users, and send password reset emails.
defineIdp("my-idp", {
clients: ["my-client"],
permission: {
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
update: [
{
conditions: [
[{ user: "role" }, "=", "ADMIN"],
[{ newIdpUser: "name" }, "!=", { oldIdpUser: "name" }],
],
permit: true,
},
],
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
sendPasswordResetEmail: [{ conditions: [], permit: false }],
},
});Operations:
create- Controls who can create IdP usersread- Controls who can read IdP usersupdate- Controls who can update IdP usersdelete- Controls who can delete IdP userssendPasswordResetEmail- Controls who can send password reset emails. The examples above disable this operation; to enable it, use a permission such as[{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }].
Policy fields: each entry in an operation's policy array supports:
conditions- Array of conditions evaluated for the policy (see Operands/Operators below)permit- Whether to allow (true) or deny (false) when the conditions matchdescription- (Optional) Human-readable description of the policy
Operands:
{ user: "field" }- Authenticated user's attribute. Built-in fields:"id"(user ID),"_loggedIn"(boolean, whether the user is authenticated). User-defined attributes (e.g.,"role") are also available when configured viauserProfile.attributesormachineUserAttributesindefineAuth(){ idpUser: "field" }- IdP user field (for create/read/delete). Allowed values:"id","name","disabled"{ oldIdpUser: "field" }- Previous IdP user field value (for update only). Allowed values:"id","name","disabled"{ newIdpUser: "field" }- New IdP user field value (for update only). Allowed values:"id","name","disabled"- Literal values:
string,boolean,string[],boolean[]
Operators: "=", "!=", "in", "not in"
Helper: unsafeAllowAllIdPPermission grants full access without conditions. Intended only for development and testing.
import { unsafeAllowAllIdPPermission } from "@tailor-platform/sdk";
defineIdp("my-idp", {
clients: ["my-client"],
permission: unsafeAllowAllIdPPermission,
});clients
OAuth client names that can use this IdP:
defineIdp("my-idp", {
clients: ["default-client", "mobile-client"],
});userAuthPolicy
User authentication policy. Controls password requirements, the identifier used for login, allowed email domains, and social login providers. Every field is optional. The boolean options default to disabled, and the password length fields default to a minimum of 6 and a maximum of 4096.
defineIdp("my-idp", {
clients: ["my-client"],
userAuthPolicy: {
useNonEmailIdentifier: false,
allowSelfPasswordReset: true,
passwordRequireUppercase: true,
passwordRequireLowercase: true,
passwordRequireNonAlphanumeric: true,
passwordRequireNumeric: true,
passwordMinLength: 8,
passwordMaxLength: 128,
},
});Login behavior:
useNonEmailIdentifier- Allow a non-email identifier (username) instead of requiring an email address. Defaultfalse.allowSelfPasswordReset- Show the "Forgot password?" flow so users can reset their own password. Defaultfalse.disablePasswordAuth- Remove password authentication entirely. Defaultfalse. Requires at least one social login provider to be enabled.
Password requirements:
passwordRequireUppercase- Require at least one uppercase letter. Defaultfalse.passwordRequireLowercase- Require at least one lowercase letter. Defaultfalse.passwordRequireNumeric- Require at least one numeric character. Defaultfalse.passwordRequireNonAlphanumeric- Require at least one non-alphanumeric character. Defaultfalse.passwordMinLength- Minimum password length. Must be between 6 and 30. Default6.passwordMaxLength- Maximum password length. Must be between 6 and 4096. Default4096.
Email domains and social login:
allowedEmailDomains- Restrict registration to these email domains. An empty list (the default) allows all domains, but a non-empty list is required whenallowGoogleOauthorallowMicrosoftOauthis enabled.allowGoogleOauth- Enable the "Sign in with Google" button. Defaultfalse.allowMicrosoftOauth- Enable the "Sign in with Microsoft" button. Defaultfalse.
Constraints: the following combinations are rejected at parse time.
passwordMinLengthmust be less than or equal topasswordMaxLength.- A non-empty
allowedEmailDomainscannot be combined withuseNonEmailIdentifier: true(an empty list is allowed). EnablingallowGoogleOauthorallowMicrosoftOauthis likewise rejected withuseNonEmailIdentifier: true(leaving themfalseor unset is fine). allowGoogleOauthrequires a non-emptyallowedEmailDomains.allowMicrosoftOauthrequires both a non-emptyallowedEmailDomainsanddisablePasswordAuth: true.disablePasswordAuthrequiresallowGoogleOauthorallowMicrosoftOauth, and cannot be combined withallowSelfPasswordReset.
gqlOperations
Controls which GraphQL user-management operations the IdP exposes. All operations are enabled by default. Use this to turn operations off entirely, independent of the permission policies that decide who may call them.
defineIdp("my-idp", {
clients: ["my-client"],
gqlOperations: {
create: true,
read: true,
update: true,
delete: false,
sendPasswordResetEmail: false,
},
});Fields: each field defaults to true (enabled). Set a field to false to disable that operation.
create- The_createUsermutation.read- The_usersand_userquery operations.update- The_updateUsermutation.delete- The_deleteUsermutation.sendPasswordResetEmail- The_sendPasswordResetEmailmutation.
Shortcut: pass the string "query" to expose a read-only IdP. It enables read and disables every mutation.
defineIdp("my-idp", {
clients: ["my-client"],
gqlOperations: "query",
});authorization (optional, legacy)
Legacy access control field. Use permission instead for fine-grained per-operation control. This field is kept for backward compatibility.
defineIdp("my-idp", {
clients: ["default-client"],
authorization: "loggedIn", // Only logged-in users can manage
});Values:
"insecure"- No authentication required (use only for development)"loggedIn"- Requires authenticated user{ cel: "<expression>" }- Custom authorization logic using CEL
emailConfig
Namespace-level email configuration defaults. Per-request values take priority over these defaults.
defineIdp("my-idp", {
clients: ["my-client"],
permission: {
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
update: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
sendPasswordResetEmail: [{ conditions: [], permit: false }],
},
emailConfig: {
fromName: "My App",
passwordResetSubject: "Reset your password",
},
});Fields:
fromName- Default sender display name for emails. Empty means use mailer default.passwordResetSubject- Default subject for password reset emails. Empty means use localized default.
Validation: Each field must be 200 characters or less and must not contain newline characters.
lang
UI language for the IdP-hosted pages such as the login and password reset screens.
defineIdp("my-idp", {
clients: ["my-client"],
lang: "ja",
});Values: "en" or "ja".
publishUserEvents
Publish IdP user lifecycle events (idp.user.created, idp.user.updated, idp.user.deleted). These events are consumed by executors that use idpUserCreatedTrigger, idpUserUpdatedTrigger, idpUserDeletedTrigger, or idpUserTrigger.
defineIdp("my-idp", {
clients: ["my-client"],
publishUserEvents: true,
});Auto-configuration: When publishUserEvents is omitted, the SDK enables it automatically during apply for each IdP that is targeted by an executor's idpUser trigger. Targeting is per-IdP: an executor specifies which IdP it subscribes to via the trigger's idp option (required in multi-IdP projects). Set the value explicitly to override:
publishUserEvents: true: always publish events.publishUserEvents: false: never publish events.applyrejects this with an error if any executor'sidpUsertrigger targets this IdP — either removepublishUserEvents: falseor remove the matching trigger.
Using idp.provider()
The idp.provider() method creates a type-safe reference to the IdP for use in Auth configuration. The client name is validated at compile time against the clients defined in the IdP.
import { defineIdp, defineAuth, defineConfig } from "@tailor-platform/sdk";
import { user } from "./tailordb/user";
const idp = defineIdp("my-idp", {
clients: ["default-client", "mobile-client"],
permission: {
create: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
read: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
update: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
delete: [{ conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true }],
sendPasswordResetEmail: [{ conditions: [], permit: false }],
},
});
const auth = defineAuth("my-auth", {
userProfile: {
type: user,
usernameField: "email",
attributes: { role: true },
},
// Type-safe: only "default-client" or "mobile-client" are allowed
idProvider: idp.provider("my-provider", "default-client"),
});
export default defineConfig({
idp: [idp],
auth,
});Parameters:
idp.provider(
"provider-name", // Name for the provider reference
"client-name", // Must be one of the clients defined in the IdP
);The second argument only accepts client names that were defined in the clients array of the IdP configuration.