Auth
Configure providers, session duration, MFA, and principal fields in Inspire.
The auth block defines the identity model the rest of your application uses. It is where you declare:
- which sign-in providers exist
- how long sessions last
- whether MFA is optional, required, or disabled
- which principal attributes are available to policies and server code
Syntax
auth {
providers: [email, google],
sessionDuration: 30d,
mfa: optional,
principal {
displayName: string @from(Profile.displayName),
organizationId: Organization.id? @from(Profile.organizationId),
}
}What It Controls
providerscontrols the available sign-in methodssessionDurationsets session lifetimemfacontrols the MFA policyprincipalprojects app-specific data into the authenticated request context
Providers And Session Settings
auth {
providers: [email, google, github],
sessionDuration: 30d,
mfa: optional,
}Recommended first version:
- start with
email - add social providers when the product needs them
- keep
sessionDurationlong enough for normal use but not so long that sessions feel effectively permanent
Principal Attributes
The principal block is one of the most important parts of the auth model. It decides which identity-related fields the rest of the platform can rely on.
There are two main patterns:
@from(...)for a single value derived from related entity data@selectFrom(...)for a value the user chooses from a valid set, such as a current organization
@from
Use @from(...) when the value should resolve to one row:
principal {
displayName: string @from(Profile.displayName),
}This is the normal pattern for profile fields and other stable user attributes.
@selectFrom
Use @selectFrom(...) when the principal needs a selected context:
principal {
organizationId: Organization.id @selectFrom(OrgMembership.orgId),
}This is the right pattern for multi-tenant apps where a user can act inside one organization at a time.
Combining Them
These two mechanisms are often used together:
auth {
providers: [email, google],
sessionDuration: 30d,
principal {
organizationId: Organization.id @selectFrom(OrgMembership.orgId),
organizationRole: OrgRole @from(
OrgMembership.role,
where OrgMembership.orgId == principal.organizationId
),
}
}That lets the principal carry both the selected tenant and the role inside that tenant.
When To Use It
Use the auth block whenever your app has signed-in users. It defines the identity model the rest of the platform relies on.
Recommended Pattern
- start with the providers you actually need
- keep principal attributes small and stable
- project only the values used broadly in policies or server code
- use
@fromfor single-valued attributes - use
@selectFromfor user-selected context values
Canonical Example
auth {
providers: [email, google],
sessionDuration: 30d,
mfa: optional,
principal {
displayName: string @from(Profile.displayName),
organizationId: Organization.id @selectFrom(OrgMembership.orgId),
organizationRole: OrgRole @from(
OrgMembership.role,
where OrgMembership.orgId == principal.organizationId
),
}
}Practical Guidance
Good auth design in Kizaki usually means:
- identity stays simple
- app-specific user data stays in your own entities
- the principal only contains the values used often across policies and workflows
If the principal starts looking like a second user profile table, it is probably doing too much.
Related guide: Authentication