Permission Resolvers
Permission resolvers decide whether an action is allowed in the UI.
Permission checks in VibeFlui improve UI behavior, but the backend must still enforce authorization.
Schema-level permission
schemas/users/user-actions.schema.ts
export const usersSchema = {
version: "1.0.0",
resource: "users",
permissions: {
create: "users.canCreate",
update: "users.canUpdate",
delete: "users.canDelete"
},
actions: {
delete: {
enabled: true,
label: "Delete",
icon: "lucide:trash-2",
variant: "danger",
handler: "users.delete"
}
},
registry: {
permissionResolvers: ["users.canCreate", "users.canUpdate", "users.canDelete"]
}
} as const;Action-level permission
schemas/users/user-actions.ts
export const deleteAction = {
key: "delete",
label: "Delete",
permission: "users.canDelete"
} as const;Runtime registry
lib/vibeflui/registry.ts
import { createRegistry } from "@vibeflui/core";
export const registry = createRegistry({
permissionResolvers: {
"users.canDelete": async ({ row, permissionContext }) => {
const hasPermission = permissionContext?.permissions?.includes("users:delete");
const isOwner = row?.role === "owner";
return Boolean(hasPermission && !isOwner);
}
}
});Permission context
Pass roles, permissions, user data, or custom values through FluiKitProvider.
app/users/page.tsx
<FluiKitProvider
registry={registry}
permissionContext={{
roles: ["admin"],
permissions: ["users:create", "users:update", "users:delete"],
user: { id: "user_1" }
}}
>
<FluiKit schema={usersSchema} />
</FluiKitProvider>String and array permissions
If a permission string has no resolver, runtime checks permissionContext.roles and permissionContext.permissions.
schemas/users/user-actions.schema.ts
export const usersSchema = {
version: "1.0.0",
resource: "users",
actions: {
create: {
label: "Create user",
permission: "users:create"
},
delete: {
label: "Delete",
permission: ["admin", "owner"]
}
}
} as const;An array passes when at least one role or permission is present.
Condition permissions
Permissions can also use conditions.
schemas/users/user-actions.schema.ts
export const usersSchema = {
version: "1.0.0",
resource: "users",
permissions: {
approve: {
key: "status",
operator: "equals",
value: "pending"
}
},
actions: {
row: [
{
key: "approve",
label: "Approve",
handler: "users.approve"
}
]
}
} as const;Condition objects are supported in root permissions. Action-level permission accepts a string or string array.
Backend responsibility
Never rely on UI permission checks alone. A hidden or disabled button is not authorization. The backend must reject unauthorized requests.