permissions.proto 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. syntax = "proto3";
  2. package chatto.admin.v1;
  3. import "buf/validate/validate.proto";
  4. import "chatto/api/v1/roles.proto";
  5. // Trinary permission decision used by permission matrices and write requests.
  6. enum PermissionDecision {
  7. // Unspecified decision; rejected for writes.
  8. PERMISSION_DECISION_UNSPECIFIED = 0;
  9. // Explicit allow.
  10. PERMISSION_DECISION_ALLOW = 1;
  11. // Explicit deny.
  12. PERMISSION_DECISION_DENY = 2;
  13. // No explicit decision; clears the permission state on writes.
  14. PERMISSION_DECISION_NONE = 3;
  15. }
  16. // Scope tier for permission matrices and write requests.
  17. enum PermissionScopeKind {
  18. // Unspecified scope; treated as server scope where older clients omit it.
  19. PERMISSION_SCOPE_KIND_UNSPECIFIED = 0;
  20. // Server tier.
  21. PERMISSION_SCOPE_KIND_SERVER = 1;
  22. // Room-group tier.
  23. PERMISSION_SCOPE_KIND_GROUP = 2;
  24. // Room tier.
  25. PERMISSION_SCOPE_KIND_ROOM = 3;
  26. }
  27. // Permission scope reference.
  28. message PermissionScope {
  29. // Scope tier.
  30. PermissionScopeKind kind = 1 [(buf.validate.field).enum.defined_only = true];
  31. // Scope ID for group or room scope. Empty for server scope.
  32. string id = 2;
  33. }
  34. // Permission grants and denials at a single tier.
  35. message TierPermissions {
  36. // Explicitly granted permissions.
  37. repeated string permissions = 1;
  38. // Explicitly denied permissions.
  39. repeated string permission_denials = 2;
  40. }
  41. // One role's permission state at a single tier.
  42. message TierRole {
  43. reserved 1 to 5;
  44. reserved "role_name", "display_name", "description", "is_system", "position";
  45. // Explicit state at this tier.
  46. TierPermissions override = 6;
  47. // Allows inherited from broader tiers.
  48. repeated string inherited_allows = 7;
  49. // Denials inherited from broader tiers.
  50. repeated string inherited_denials = 8;
  51. // Public role metadata.
  52. chatto.api.v1.Role role = 9;
  53. }
  54. // Role permission matrix for one tier.
  55. message TierRoles {
  56. // Permissions configurable at this tier.
  57. repeated string applicable_permissions = 1;
  58. // Roles sorted by position.
  59. repeated TierRole roles = 2;
  60. }
  61. // Request a role-permission tier matrix.
  62. message GetRolePermissionTierMatrixRequest {
  63. // Target scope. Omit or use SERVER for server scope.
  64. PermissionScope scope = 1;
  65. }
  66. // Response containing a role-permission tier matrix.
  67. message GetRolePermissionTierMatrixResponse {
  68. // Requested matrix.
  69. TierRoles matrix = 1;
  70. }
  71. // Matrix column scope.
  72. message PermissionMatrixScope {
  73. // Stable scope ID for the server, a group, or a room.
  74. string id = 1;
  75. // Human-readable label.
  76. string label = 2;
  77. // Scope tier.
  78. PermissionScopeKind kind = 3;
  79. // Parent group ID for room scopes.
  80. string parent_group_id = 4;
  81. }
  82. // Matrix cell for one permission and scope.
  83. message PermissionMatrixCell {
  84. // Permission identifier.
  85. string permission = 1;
  86. // Scope ID matching PermissionMatrixScope.id.
  87. string scope_id = 2;
  88. // Explicit decision at this scope.
  89. PermissionDecision override = 3;
  90. // Effective decision at this scope.
  91. PermissionDecision effective = 4;
  92. }
  93. // Permission matrix for one role across all scopes.
  94. message RolePermissionMatrix {
  95. // Role name.
  96. string role_name = 1;
  97. // Permissions rendered as rows.
  98. repeated string applicable_permissions = 2;
  99. // Scopes rendered as columns.
  100. repeated PermissionMatrixScope scopes = 3;
  101. // Sparse matrix cells.
  102. repeated PermissionMatrixCell cells = 4;
  103. }
  104. // Request one role's permission matrix.
  105. message GetRolePermissionMatrixRequest {
  106. // Stable role name.
  107. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  108. }
  109. // Response containing one role's permission matrix.
  110. message GetRolePermissionMatrixResponse {
  111. // Requested matrix.
  112. RolePermissionMatrix matrix = 1;
  113. }
  114. // Permission matrix for one user across all scopes.
  115. message UserPermissionMatrix {
  116. // User ID.
  117. string user_id = 1;
  118. // Permissions rendered as rows.
  119. repeated string applicable_permissions = 2;
  120. // Scopes rendered as columns.
  121. repeated PermissionMatrixScope scopes = 3;
  122. // Sparse matrix cells.
  123. repeated PermissionMatrixCell cells = 4;
  124. }
  125. // One resource-oriented permission decision at a concrete scope.
  126. //
  127. // This is the row-oriented counterpart to PermissionMatrixCell. Prefer this
  128. // shape when building integrations that do not need matrix column joins.
  129. message ScopedPermissionDecision {
  130. // Permission identifier.
  131. string permission = 1;
  132. // Server, group, or room scope this decision applies to.
  133. PermissionScope scope = 2;
  134. // Explicit decision stored at this scope.
  135. PermissionDecision override = 3;
  136. // Effective decision after inherited broader scopes are applied.
  137. PermissionDecision effective = 4;
  138. }
  139. // Stored permission decision returned after a write.
  140. message PermissionDecisionUpdate {
  141. // Permission identifier.
  142. string permission = 1;
  143. // Server, group, or room scope this decision applies to.
  144. PermissionScope scope = 2;
  145. // Stored decision after the write. NONE means no explicit decision remains.
  146. PermissionDecision decision = 3;
  147. }
  148. // Request explicit/effective permission decisions for one role.
  149. message ListRolePermissionDecisionsRequest {
  150. // Stable role name.
  151. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  152. }
  153. // Resource-oriented permission decisions for one role.
  154. message ListRolePermissionDecisionsResponse {
  155. // Stable role name.
  156. string role_name = 1;
  157. // Permission decisions keyed by permission and typed scope.
  158. repeated ScopedPermissionDecision decisions = 2;
  159. }
  160. // Request explicit/effective permission decisions for one user.
  161. message ListUserPermissionDecisionsRequest {
  162. // User ID.
  163. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  164. }
  165. // Resource-oriented permission decisions for one user.
  166. message ListUserPermissionDecisionsResponse {
  167. // User ID.
  168. string user_id = 1;
  169. // Permission decisions keyed by permission and typed scope.
  170. repeated ScopedPermissionDecision decisions = 2;
  171. }
  172. // Level at which a permission explanation found a decision.
  173. enum PermissionDecisionLevel {
  174. // No decision level was reached.
  175. PERMISSION_DECISION_LEVEL_UNSPECIFIED = 0;
  176. // Server-level role or user decision.
  177. PERMISSION_DECISION_LEVEL_SERVER = 1;
  178. // Room-group-level role or user decision.
  179. PERMISSION_DECISION_LEVEL_GROUP = 2;
  180. // Room-level role or user decision.
  181. PERMISSION_DECISION_LEVEL_ROOM = 3;
  182. }
  183. // One explicit decision encountered while explaining a permission.
  184. message PermissionTraceEntry {
  185. // Level at which this decision was observed.
  186. PermissionDecisionLevel level = 1;
  187. // Role name or policy marker that produced the decision.
  188. string role_name = 2;
  189. // Decision observed at this trace step.
  190. PermissionDecision decision = 3;
  191. // Whether this entry is the winning decision.
  192. bool applied = 4;
  193. }
  194. // Full decision trace for one permission and target user.
  195. message PermissionExplanation {
  196. // Permission identifier.
  197. string permission = 1;
  198. // Overall decision after applying deny-wins resolution.
  199. PermissionDecision state = 2;
  200. // Level of the winning decision, when state is not NONE.
  201. PermissionDecisionLevel decided_at = 3;
  202. // Role name or policy marker that produced the winning decision.
  203. string decided_by_role = 4;
  204. // Ordered decision trace. The first entry is the winning decision.
  205. repeated PermissionTraceEntry trace = 5;
  206. }
  207. // Request permission explanations for a user at server or room scope.
  208. message ExplainPermissionsRequest {
  209. // User whose permissions should be explained.
  210. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  211. // Optional room scope. Omit for server-scoped permissions.
  212. string room_id = 2;
  213. }
  214. // Permission explanations for all permissions applicable at the requested scope.
  215. message ExplainPermissionsResponse {
  216. // Explanation rows sorted by permission metadata order.
  217. repeated PermissionExplanation explanations = 1;
  218. }
  219. // Request one user's permission matrix.
  220. message GetUserPermissionMatrixRequest {
  221. // User ID.
  222. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  223. }
  224. // Response containing one user's permission matrix.
  225. message GetUserPermissionMatrixResponse {
  226. // Requested matrix.
  227. UserPermissionMatrix matrix = 1;
  228. }
  229. // Request to set one role permission state.
  230. message SetRolePermissionRequest {
  231. // Role name.
  232. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  233. // Permission identifier.
  234. string permission = 2 [(buf.validate.field).string.min_len = 1];
  235. // New decision. NONE clears the explicit state.
  236. PermissionDecision decision = 3 [(buf.validate.field).enum = {
  237. defined_only: true
  238. not_in: [0]
  239. }];
  240. // Target scope. Omit or use SERVER for server scope.
  241. PermissionScope scope = 4;
  242. }
  243. // Result of setting one role permission state.
  244. message SetRolePermissionResponse {
  245. // Updated permission decision for the requested role/scope cell.
  246. PermissionDecisionUpdate decision = 1;
  247. }
  248. // Request to set one user permission state.
  249. message SetUserPermissionRequest {
  250. // Target user ID.
  251. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  252. // Permission identifier.
  253. string permission = 2 [(buf.validate.field).string.min_len = 1];
  254. // New decision. NONE clears the explicit state.
  255. PermissionDecision decision = 3 [(buf.validate.field).enum = {
  256. defined_only: true
  257. not_in: [0]
  258. }];
  259. // Target scope. Omit or use SERVER for server scope.
  260. PermissionScope scope = 4;
  261. }
  262. // Result of setting one user permission state.
  263. message SetUserPermissionResponse {
  264. // Updated permission decision for the requested user/scope cell.
  265. PermissionDecisionUpdate decision = 1;
  266. }
  267. // Provides permission matrix reads and admin permission writes.
  268. service AdminPermissionService {
  269. // Gets the role-permission matrix for a single tier. Requires role.manage
  270. // for server/group scope; room scope requires role.manage or room.manage in
  271. // that room.
  272. rpc GetRolePermissionTierMatrix(GetRolePermissionTierMatrixRequest) returns (GetRolePermissionTierMatrixResponse);
  273. // Gets one role's full permission matrix. Requires role.manage. Returns
  274. // NOT_FOUND when the role does not exist.
  275. rpc GetRolePermissionMatrix(GetRolePermissionMatrixRequest) returns (GetRolePermissionMatrixResponse);
  276. // Lists one role's permission decisions as resource-oriented rows. Requires
  277. // role.manage. Returns NOT_FOUND when the role does not exist.
  278. rpc ListRolePermissionDecisions(ListRolePermissionDecisionsRequest) returns (ListRolePermissionDecisionsResponse);
  279. // Gets one user's full permission matrix. Requires user.manage-permissions.
  280. // Returns NOT_FOUND when the user does not exist.
  281. rpc GetUserPermissionMatrix(GetUserPermissionMatrixRequest) returns (GetUserPermissionMatrixResponse);
  282. // Lists one user's permission decisions as resource-oriented rows. Requires
  283. // user.manage-permissions. Returns NOT_FOUND when the user does not exist.
  284. rpc ListUserPermissionDecisions(ListUserPermissionDecisionsRequest) returns (ListUserPermissionDecisionsResponse);
  285. // Explains permission resolution for another user. Requires role.manage.
  286. rpc ExplainPermissions(ExplainPermissionsRequest) returns (ExplainPermissionsResponse);
  287. // Sets one role permission decision. Requires role.manage or scoped room.manage for room scope.
  288. rpc SetRolePermission(SetRolePermissionRequest) returns (SetRolePermissionResponse);
  289. // Sets one user permission decision. Requires user.manage-permissions.
  290. rpc SetUserPermission(SetUserPermissionRequest) returns (SetUserPermissionResponse);
  291. }