// 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); // Support diagnostics. Requires read on diagnostics:internal-errors. rpc ListInternalErrors(ListInternalErrorsRequest) returns (ListInternalErrorsResponse); rpc GetInternalError(GetInternalErrorRequest) returns (InternalError); // 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, table, or diagnostics. 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 InternalError { string reference_id = 1; string user_id = 2; string username = 3; string grpc_method = 4; string detail = 5; int64 occurred_at_unix_milliseconds = 6; } message ListInternalErrorsRequest { // Every non-empty text/UUID field is an optional filter. Username and method // use case-insensitive substring matching. string reference_id = 1; string user_id = 2; string username = 3; string grpc_method = 4; int64 occurred_from_unix_seconds = 5; int64 occurred_to_unix_seconds = 6; InternalErrorSort sort = 7; // Unspecified sort always means newest first. For an explicit sort, false is // ascending and true is descending. bool descending = 8; // Defaults to 100 and is capped at 500. uint32 limit = 9; uint64 offset = 10; } enum InternalErrorSort { INTERNAL_ERROR_SORT_UNSPECIFIED = 0; INTERNAL_ERROR_SORT_OCCURRED_AT = 1; INTERNAL_ERROR_SORT_REFERENCE_ID = 2; INTERNAL_ERROR_SORT_USERNAME = 3; INTERNAL_ERROR_SORT_GRPC_METHOD = 4; } message ListInternalErrorsResponse { repeated InternalError errors = 1; uint64 total_count = 2; } message GetInternalErrorRequest { string reference_id = 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; }