// proto/auth.proto syntax = "proto3"; package komp_ac.auth; import "common.proto"; service AuthService { rpc Register(RegisterRequest) returns (AuthResponse); rpc Login(LoginRequest) returns (LoginResponse); // Changes the authenticated user's password after verifying the current one. rpc ChangePassword(ChangePasswordRequest) returns (PasswordOperationResponse); rpc GetAuthorization(GetAuthorizationRequest) returns (AuthorizationSnapshot); rpc SetTimezone(SetTimezoneRequest) returns (UserPreferences); // Ends the caller's own sessions. Every token issued to them before this // call, on every device, stops being accepted -- including the one used to // make the call, so the caller must log in again afterwards. Discarding a // token client-side is not a logout; this is. rpc Logout(LogoutRequest) returns (LogoutResponse); // Ends every session of another user, for a leaked token or a departing // account. Requires the struct:user area, and the target must rank strictly // below the caller. rpc RevokeUserSessions(RevokeUserSessionsRequest) returns (RevokeUserSessionsResponse); // 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); rpc ListGrantableObjects(ListGrantableObjectsRequest) returns (ListGrantableObjectsResponse); // User administration. rpc AssignUserRole(AssignUserRoleRequest) returns (UserSummary); // Resets a lower-ranked user's password. rpc ResetUserPassword(ResetUserPasswordRequest) returns (PasswordOperationResponse); rpc ListUsers(ListUsersRequest) returns (ListUsersResponse); } message RegisterRequest { string username = 1; string email = 2; string password = 3; string password_confirmation = 4; 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; // Always 'guest' for a self-registration } message ChangePasswordRequest { string current_password = 1; string new_password = 2; string new_password_confirmation = 3; } message PasswordOperationResponse {} message LoginRequest { string identifier = 1; // Can be username or email string password = 2; } message LoginResponse { string access_token = 1; // JWT token string token_type = 2; // Usually "Bearer" int32 expires_in = 3; // Expiration in seconds (86400 for 24 hours) string user_id = 4; // User's UUID in string format string role = 5; // User's role string username = 6; AuthorizationSnapshot authorization = 7; string timezone = 8; string phone_country = 9; } message SetTimezoneRequest { string timezone = 1; // IANA timezone, for example Europe/Bratislava } message UserPreferences { string timezone = 1; } message LogoutRequest {} message LogoutResponse {} message RevokeUserSessionsRequest { string username = 1; } message RevokeUserSessionsResponse {} message GetAuthorizationRequest {} message Permission { // Canonical object string, one of: // struct: structural area, never grantable at runtime // data:/ one root table and its whole template family // data:/* every table in a profile, present and future // data:* every table everywhere // journal: 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; // '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 {} message ListRolesResponse { repeated Role roles = 1; } 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 ListGrantableObjectsRequest { // The role being edited. The response contains only actions that may be // granted to this role by the caller. string target_role = 1; } message GrantableObject { // Canonical value accepted by GrantPermission, for example // data:acme/invoices. string object = 1; // Empty only for the data:* and journal:* global wildcards. string profile = 2; // Set only for a table-family root. string table = 3; // One of global_data, global_journal, profile, journal, or table. string kind = 4; // Actions the caller may grant to target_role for this object. repeated string allowed_actions = 5; } message ListGrantableObjectsResponse { repeated GrantableObject objects = 1; } message AssignUserRoleRequest { string username = 1; string role = 2; } message ResetUserPasswordRequest { string username = 1; string new_password = 2; string new_password_confirmation = 3; } message UserSummary { string id = 1; string username = 2; string email = 3; string role = 4; } message ListUsersRequest {} message ListUsersResponse { repeated UserSummary users = 1; }