Permissions

Grant the new routes in thunder-core's RBAC - the step that decides what each role sees in the dashboard.

thunder-core denies every route that no policy grants. You have just added three resources, so right now all of them return 403 - and the dashboard you are about to generate would be empty.

This page is short, but skipping it is the single most common way to get stuck in this example.

The Permission Strings You Created

Permissions are scope.action, where scope is the router's function name and action is the handler's function name. Your three routers produced:

ScopeActions
equipmentcreate, get, count, update, del
customerscreate, get, count, update, del
rentalscreate, get, count, update, cancelRental

rentals has no del - you disabled it and replaced it with cancelRental, so that is the string to grant.

A bare scope such as equipment grants every action in that router, and * grants everything. Use the bare form for a role that should have full access to a resource.

Designing the Two Roles

RoleShould be able to
AgentLook up equipment, manage customers, book and update rentals
ManagerEverything, plus cancelling a rental

Which becomes:

// agent
["equipment.get", "equipment.count", "customers", "rentals.get", "rentals.count", "rentals.create", "rentals.update"]

// manager
["equipment", "customers", "rentals"]

Note the agent gets equipment.get and equipment.count but not equipment.create or equipment.update - they can pick equipment for a rental, but not change the catalogue.

Granting Them

Edit scripts/syncAccessControl.ts to add your policies and attach them to roles, then run the plugin setup:

deno task setup:plugin -n Huruf-Tech/thunder-core --envs=development

syncAccessControl is idempotent - it upserts through ACManager, so re-running it after adding permissions is safe. See Setup & Lifecycle.

Use the management routes that thunder-core ships, so you do not have to touch the seed or restart:

  • routes/accessControlPolicies.ts - create or edit a policy (a named bundle of permission strings)
  • routes/accessControl.ts - attach policies to a role

This is the right path once you have real data. See Access Control.

Read scripts/syncAccessControl.ts for the exact document shape and the default role names before you edit it - the seeded defaults include roles like guest, user and admin.

Why This Decides the Dashboard

This is the part worth internalising. Thunder UI shows a module only if:

ThunderSDK.isPermitted(name, "get") || ThunderSDK.isPermitted(name, "create")

So your RBAC is the navigation:

  • An agent signs in and sees Equipment, Customers and Rentals - but no create button on equipment.
  • Strip equipment.get and equipment.count from a role and the Equipment module vanishes from their sidebar entirely.
  • Hide every module in the group and the Rental Desk group header disappears on its own - a group shows only when a child is visible.

You never write a permission check in the frontend. One role definition drives both the API and the UI.

Permissions are registered before the app renders, via registerPermissions(). That is why visibility never flickers - but it also means a permission change needs a reload to take effect. See Authentication & Multi-Tenancy.

With the roles in place, generate the dashboard. On to the Dashboard.


On this page