Permissions
The permission model in one page. The full feature walkthrough is Authorization.
The model
- A permission is a dotted string:
feature.action(e.g.projects.read,users.update). - Features declare their permissions as
public const stringconstants in a*Permissionsclass; a catalog is aggregated from them at startup by reflection — there's no central list to maintain. - Roles bundle permissions. Users hold roles. A user's effective permissions are the union across their roles.
- Wildcards expand at check time:
projects.*grants everyprojects.x.*grants everything — it's held by the built-in Admin role, and covers permissions added by features that don't exist yet.
Enforcement
Gate an endpoint with .RequirePermission("projects.read"). The result:
| Caller | Response |
|---|---|
| Not signed in | 401 Unauthorized |
| Signed in, lacks the permission | 403 Forbidden |
| Signed in, has it (directly or via wildcard) | the handler runs |
Permissions ride in the auth cookie and refresh on the 1-minute validation interval, so a role change reaches its members within ~1 minute (or immediately on next sign-in).
Built-in roles
| Role | Grants | Notes |
|---|---|---|
| Admin | * | Can't be renamed or deleted. |
| Member | catalog read (default) | The default role for new sign-ups; fully editable. |
Adding one
Declare a constant, gate the endpoint, assign via /admin/roles. The Add a permission recipe has the three steps.