77 lines
2.5 KiB
Text
77 lines
2.5 KiB
Text
|
|
# Role Registry — Single Source of Truth
|
||
|
|
#
|
||
|
|
# Canonical role definitions for the application. Every layer that refers
|
||
|
|
# to roles MUST derive from this file:
|
||
|
|
#
|
||
|
|
# rbac.ncl — group names validated against this list at eval time
|
||
|
|
# DB migrations — user_roles table seeded from entries where db_seed = true
|
||
|
|
# Rust Role enum — rustelo_core_lib::auth::Role variants mapped via rust_variant
|
||
|
|
#
|
||
|
|
# DB migration note:
|
||
|
|
# Migration 3 seeds only "admin" and "user".
|
||
|
|
# Roles added here with db_seed = true that are absent from the DB require
|
||
|
|
# a new migration:
|
||
|
|
# INSERT INTO user_roles (name, description) VALUES
|
||
|
|
# ('supervisor', '...'), ('moderator', '...'), ('guest', '...')
|
||
|
|
# ON CONFLICT (name) DO NOTHING;
|
||
|
|
#
|
||
|
|
# Rust enum note:
|
||
|
|
# rustelo_core_lib::auth::Role = Admin | Moderator | User | Guest | Custom(String)
|
||
|
|
# Roles without a dedicated variant use rust_variant = "Custom" — the name
|
||
|
|
# string becomes the Custom payload when parsing from JWT claims.
|
||
|
|
#
|
||
|
|
# Validate: nickel export site/config/roles.ncl
|
||
|
|
|
||
|
|
let C = import "rbac/roles_contracts.ncl" in
|
||
|
|
|
||
|
|
{
|
||
|
|
roles = [
|
||
|
|
{
|
||
|
|
name = "admin",
|
||
|
|
description = "Full system access — unrestricted access to all resources and admin functions",
|
||
|
|
db_seed = true,
|
||
|
|
is_system = true,
|
||
|
|
parent_roles = [],
|
||
|
|
rust_variant = "Admin",
|
||
|
|
db_level = 100,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name = "supervisor",
|
||
|
|
description = "Elevated user with notification broadcast rights; inherits user permissions",
|
||
|
|
db_seed = true,
|
||
|
|
is_system = false,
|
||
|
|
parent_roles = ["user"],
|
||
|
|
rust_variant = "Custom",
|
||
|
|
db_level = 40,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name = "moderator",
|
||
|
|
description = "Content moderator — read/write/delete content and access admin content pages",
|
||
|
|
db_seed = true,
|
||
|
|
is_system = false,
|
||
|
|
parent_roles = ["user"],
|
||
|
|
rust_variant = "Moderator",
|
||
|
|
db_level = 30,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name = "user",
|
||
|
|
description = "Regular authenticated user with access to their own data and public content",
|
||
|
|
db_seed = true,
|
||
|
|
is_system = true,
|
||
|
|
is_default = true,
|
||
|
|
parent_roles = [],
|
||
|
|
rust_variant = "User",
|
||
|
|
db_level = 10,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name = "guest",
|
||
|
|
description = "Virtual role for unauthenticated visitors — no DB row, used only in policy logic",
|
||
|
|
db_seed = false,
|
||
|
|
is_system = true,
|
||
|
|
parent_roles = [],
|
||
|
|
rust_variant = "Guest",
|
||
|
|
db_level = 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
} | C.RolesConfig | C.ExactlyOneDefaultRole
|