Protect User Data
This guide assumes sign-in is working. A session tells CloudConfig who made a request; model rules decide which rows they can access.
Protect Data That Belongs to a User
Relate the model to the built-in user model. Mark the owner as server-only so a browser cannot assign or change ownership. A creation hook fills it from the session after the access check:
note: model(
{
title: t.text().required(),
owner: t.relation('user').required().serverOnly(),
},
{
access: {
list: ({ user, where }) =>
user ? where('ownerId', 'eq', user.id) : false,
read: ({ user, where }) =>
user ? where('ownerId', 'eq', user.id) : false,
create: ({ user }) => user != null,
update: ({ user, where }) =>
user ? where('ownerId', 'eq', user.id) : false,
delete: ({ user, where }) =>
user ? where('ownerId', 'eq', user.id) : false,
},
hooks: {
beforeCreate: ({ user }, input) => {
if (!user) throw new Error('Sign-in required')
return { ...input, ownerId: user.id }
},
},
},
)
These rules apply to REST requests and the typed client. Requests without a session receive no private rows.
After adding the relation or user fields, generate and apply a migration with
pnpm db:generate and pnpm db:migrate.
Add Fields to a User
Use userFields when access rules need application-specific information:
auth: {
providers: { github: true },
userFields: {
role: t.select(['member', 'admin']).default('member').hidden(),
},
}
The field is included in the next migration and becomes available as
user.role. The .hidden() modifier prevents sign-up requests from assigning
the field themselves.