permissions.proto 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. // Whether an explicit allow may currently be stored for this target. Absent
  93. // when no additional delegation ceiling applies.
  94. optional bool allow_permitted = 5;
  95. }
  96. // Permission matrix for one role across all scopes.
  97. message RolePermissionMatrix {
  98. // Role name.
  99. string role_name = 1;
  100. // Permissions rendered as rows.
  101. repeated string applicable_permissions = 2;
  102. // Scopes rendered as columns.
  103. repeated PermissionMatrixScope scopes = 3;
  104. // Sparse matrix cells.
  105. repeated PermissionMatrixCell cells = 4;
  106. }
  107. // Request one role's permission matrix.
  108. message GetRolePermissionMatrixRequest {
  109. // Stable role name.
  110. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  111. }
  112. // Response containing one role's permission matrix.
  113. message GetRolePermissionMatrixResponse {
  114. // Requested matrix.
  115. RolePermissionMatrix matrix = 1;
  116. }
  117. // Permission matrix for one user across all scopes.
  118. message UserPermissionMatrix {
  119. // User ID.
  120. string user_id = 1;
  121. // Permissions rendered as rows.
  122. repeated string applicable_permissions = 2;
  123. // Scopes rendered as columns.
  124. repeated PermissionMatrixScope scopes = 3;
  125. // Sparse matrix cells.
  126. repeated PermissionMatrixCell cells = 4;
  127. }
  128. // One resource-oriented permission decision at a concrete scope.
  129. //
  130. // This is the row-oriented counterpart to PermissionMatrixCell. Prefer this
  131. // shape when building integrations that do not need matrix column joins.
  132. message ScopedPermissionDecision {
  133. // Permission identifier.
  134. string permission = 1;
  135. // Server, group, or room scope this decision applies to.
  136. PermissionScope scope = 2;
  137. // Explicit decision stored at this scope.
  138. PermissionDecision override = 3;
  139. // Effective decision after inherited broader scopes are applied.
  140. PermissionDecision effective = 4;
  141. }
  142. // Stored permission decision returned after a write.
  143. message PermissionDecisionUpdate {
  144. // Permission identifier.
  145. string permission = 1;
  146. // Server, group, or room scope this decision applies to.
  147. PermissionScope scope = 2;
  148. // Stored decision after the write. NONE means no explicit decision remains.
  149. PermissionDecision decision = 3;
  150. }
  151. // Request explicit/effective permission decisions for one role.
  152. message ListRolePermissionDecisionsRequest {
  153. // Stable role name.
  154. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  155. }
  156. // Resource-oriented permission decisions for one role.
  157. message ListRolePermissionDecisionsResponse {
  158. // Stable role name.
  159. string role_name = 1;
  160. // Permission decisions keyed by permission and typed scope.
  161. repeated ScopedPermissionDecision decisions = 2;
  162. }
  163. // Request explicit/effective permission decisions for one user.
  164. message ListUserPermissionDecisionsRequest {
  165. // User ID.
  166. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  167. }
  168. // Resource-oriented permission decisions for one user.
  169. message ListUserPermissionDecisionsResponse {
  170. // User ID.
  171. string user_id = 1;
  172. // Permission decisions keyed by permission and typed scope.
  173. repeated ScopedPermissionDecision decisions = 2;
  174. }
  175. // Level at which a permission explanation found a decision.
  176. enum PermissionDecisionLevel {
  177. // No decision level was reached.
  178. PERMISSION_DECISION_LEVEL_UNSPECIFIED = 0;
  179. // Server-level role or user decision.
  180. PERMISSION_DECISION_LEVEL_SERVER = 1;
  181. // Room-group-level role or user decision.
  182. PERMISSION_DECISION_LEVEL_GROUP = 2;
  183. // Room-level role or user decision.
  184. PERMISSION_DECISION_LEVEL_ROOM = 3;
  185. }
  186. // One explicit decision encountered while explaining a permission.
  187. message PermissionTraceEntry {
  188. // Level at which this decision was observed.
  189. PermissionDecisionLevel level = 1;
  190. // Role name, user ID, or policy marker that produced the decision.
  191. string role_name = 2;
  192. // Decision observed at this trace step.
  193. PermissionDecision decision = 3;
  194. // Whether this entry is the winning decision.
  195. bool applied = 4;
  196. }
  197. // Full decision trace for one permission and target user.
  198. message PermissionExplanation {
  199. // Permission identifier.
  200. string permission = 1;
  201. // Overall decision after resolving named subjects and the everyone baseline.
  202. PermissionDecision state = 2;
  203. // Level of the winning decision, when state is not NONE.
  204. PermissionDecisionLevel decided_at = 3;
  205. // Role name, user ID, or policy marker that produced the winning decision.
  206. string decided_by_role = 4;
  207. // Ordered decision trace. The first entry is the winning decision.
  208. repeated PermissionTraceEntry trace = 5;
  209. // Permission whose effective allow includes this permission. Empty when the
  210. // permission was resolved directly.
  211. string included_by_permission = 6;
  212. }
  213. // Request permission explanations for a user at server or room scope.
  214. message ExplainPermissionsRequest {
  215. // User whose permissions should be explained.
  216. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  217. // Optional room scope. Omit for server-scoped permissions.
  218. string room_id = 2;
  219. }
  220. // Permission explanations for all permissions applicable at the requested scope.
  221. message ExplainPermissionsResponse {
  222. // Explanation rows sorted by permission metadata order.
  223. repeated PermissionExplanation explanations = 1;
  224. }
  225. // Request one user's permission matrix.
  226. message GetUserPermissionMatrixRequest {
  227. // User ID.
  228. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  229. }
  230. // Response containing one user's permission matrix.
  231. message GetUserPermissionMatrixResponse {
  232. // Requested matrix.
  233. UserPermissionMatrix matrix = 1;
  234. }
  235. // Request to set one role permission state.
  236. message SetRolePermissionRequest {
  237. // Role name.
  238. string role_name = 1 [(buf.validate.field).string.min_len = 1];
  239. // Permission identifier.
  240. string permission = 2 [(buf.validate.field).string.min_len = 1];
  241. // New decision. NONE clears the explicit state.
  242. PermissionDecision decision = 3 [(buf.validate.field).enum = {
  243. defined_only: true
  244. not_in: [0]
  245. }];
  246. // Target scope. Omit or use SERVER for server scope.
  247. PermissionScope scope = 4;
  248. }
  249. // Result of setting one role permission state.
  250. message SetRolePermissionResponse {
  251. // Updated permission decision for the requested role/scope cell.
  252. PermissionDecisionUpdate decision = 1;
  253. }
  254. // Request to set one user permission state.
  255. message SetUserPermissionRequest {
  256. // Target user ID.
  257. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  258. // Permission identifier.
  259. string permission = 2 [(buf.validate.field).string.min_len = 1];
  260. // New decision. NONE clears the explicit state.
  261. PermissionDecision decision = 3 [(buf.validate.field).enum = {
  262. defined_only: true
  263. not_in: [0]
  264. }];
  265. // Target scope. Omit or use SERVER for server scope.
  266. PermissionScope scope = 4;
  267. }
  268. // Result of setting one user permission state.
  269. message SetUserPermissionResponse {
  270. // Updated permission decision for the requested user/scope cell.
  271. PermissionDecisionUpdate decision = 1;
  272. }
  273. // Provides permission matrix reads and admin permission writes.
  274. service AdminPermissionService {
  275. // Gets the role-permission matrix for a single tier. Server scope requires
  276. // role.manage; group and room scopes require role.manage or effective
  277. // room.manage at the requested resource.
  278. rpc GetRolePermissionTierMatrix(GetRolePermissionTierMatrixRequest) returns (GetRolePermissionTierMatrixResponse);
  279. // Gets one role's full permission matrix. Requires role.manage. Returns
  280. // NOT_FOUND when the role does not exist.
  281. rpc GetRolePermissionMatrix(GetRolePermissionMatrixRequest) returns (GetRolePermissionMatrixResponse);
  282. // Lists one role's permission decisions as resource-oriented rows. Requires
  283. // role.manage. Returns NOT_FOUND when the role does not exist.
  284. rpc ListRolePermissionDecisions(ListRolePermissionDecisionsRequest) returns (ListRolePermissionDecisionsResponse);
  285. // Gets one user's full permission matrix. Human targets require
  286. // user.manage-permissions; bot targets require ownership or bot.manage.
  287. // Returns NOT_FOUND when the user does not exist.
  288. rpc GetUserPermissionMatrix(GetUserPermissionMatrixRequest) returns (GetUserPermissionMatrixResponse);
  289. // Lists one user's permission decisions as resource-oriented rows. Human
  290. // targets require user.manage-permissions; bot targets require ownership or
  291. // bot.manage. Returns NOT_FOUND when the user does not exist.
  292. rpc ListUserPermissionDecisions(ListUserPermissionDecisionsRequest) returns (ListUserPermissionDecisionsResponse);
  293. // Explains permission resolution for another user. Requires role.manage.
  294. rpc ExplainPermissions(ExplainPermissionsRequest) returns (ExplainPermissionsResponse);
  295. // Sets one role permission decision. Server scope requires role.manage;
  296. // group and room scopes also accept effective room.manage at that resource.
  297. rpc SetRolePermission(SetRolePermissionRequest) returns (SetRolePermissionResponse);
  298. // Sets one user permission decision. Human targets require
  299. // user.manage-permissions; bot targets require ownership or bot.manage and
  300. // accept only allow or clear within the bot owner's current authority.
  301. rpc SetUserPermission(SetUserPermissionRequest) returns (SetUserPermissionResponse);
  302. }