dynamic rbac and roles

This commit is contained in:
Priec
2026-08-09 12:56:57 +02:00
parent 29ccd8d2d7
commit 4d6c18988b
10 changed files with 630 additions and 27 deletions

View File

@@ -7,11 +7,25 @@ import "common.proto";
service AuthService {
rpc Register(RegisterRequest) returns (AuthResponse);
rpc Login(LoginRequest) returns (LoginResponse);
// Claims a bootstrap account that has never had a password set.
rpc SetInitialPassword(SetInitialPasswordRequest) returns (AuthResponse);
rpc GetAuthorization(GetAuthorizationRequest) returns (AuthorizationSnapshot);
rpc SetTimezone(SetTimezoneRequest) returns (UserPreferences);
// Role administration. Every call requires the struct:role area, and every
// target role must rank strictly below the caller's own role.
rpc ListRoles(ListRolesRequest) returns (ListRolesResponse);
rpc AddRole(AddRoleRequest) returns (Role);
rpc RemoveRole(RemoveRoleRequest) returns (Role);
// Grant administration on the data plane.
rpc GrantPermission(GrantPermissionRequest) returns (RolePermissions);
rpc RevokePermission(RevokePermissionRequest) returns (RolePermissions);
rpc ListRolePermissions(ListRolePermissionsRequest) returns (RolePermissions);
// User administration.
rpc AssignUserRole(AssignUserRoleRequest) returns (UserSummary);
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}
message RegisterRequest {
@@ -19,16 +33,21 @@ message RegisterRequest {
string email = 2;
string password = 3;
string password_confirmation = 4;
string role = 5;
string timezone = 6; // IANA timezone, for example Europe/Bratislava
string phone_country = 7; // ISO 3166-1 alpha-2 country used for national phone numbers, for example SK
string timezone = 5; // IANA timezone, for example Europe/Bratislava
string phone_country = 6; // ISO 3166-1 alpha-2 country used for national phone numbers, for example SK
}
message AuthResponse {
string id = 1; // UUID in string format
string username = 2; // Registered username
string email = 3; // Registered email (if provided)
string role = 4; // Default role: 'accountant'
string role = 4; // Always 'guest' for a self-registration
}
message SetInitialPasswordRequest {
string username = 1;
string password = 2;
string password_confirmation = 3;
}
message LoginRequest {
@@ -59,18 +78,31 @@ message UserPreferences {
message GetAuthorizationRequest {}
message Permission {
string resource = 1;
// Canonical object string, one of:
// struct:<area> structural area, never grantable at runtime
// data:<profile>/<table> one root table and its whole template family
// data:<profile>/* every table in a profile, present and future
// data:* every table everywhere
// journal:<profile> one profile's accounting journal
// journal:* every profile's journal
string object = 1;
// manage for structural areas; read/insert/update/delete on the data plane.
string action = 2;
}
message AuthorizationSnapshot {
string role = 1;
// Every permission the role holds, inherited ones included.
repeated Permission permissions = 2;
}
message Role {
string name = 1;
bool built_in = 2;
// 'structural' (designs the system, never writes data) or 'data'.
string kind = 2;
bool built_in = 3;
// Role this one inherits every grant from; empty when it has no parent.
string parent = 4;
}
message ListRolesRequest {}
@@ -81,8 +113,52 @@ message ListRolesResponse {
message AddRoleRequest {
string name = 1;
// Optional data role to inherit from. Must rank below the caller.
string parent = 2;
}
message RemoveRoleRequest {
string name = 1;
}
message GrantPermissionRequest {
string role = 1;
string object = 2;
string action = 3;
}
message RevokePermissionRequest {
string role = 1;
string object = 2;
string action = 3;
}
message ListRolePermissionsRequest {
string role = 1;
}
message RolePermissions {
string role = 1;
// Grants stored against this role alone, without inherited ones.
repeated Permission permissions = 2;
// Everything the role can actually do, inheritance resolved.
repeated Permission effective_permissions = 3;
}
message AssignUserRoleRequest {
string username = 1;
string role = 2;
}
message UserSummary {
string id = 1;
string username = 2;
string email = 3;
string role = 4;
}
message ListUsersRequest {}
message ListUsersResponse {
repeated UserSummary users = 1;
}