Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions proto/lekko/bff/v1beta1/bff.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ service BFFService {
rpc Restore(RestoreRequest) returns (RestoreResponse) {}
rpc GetRepositoryLogs(GetRepositoryLogsRequest) returns (GetRepositoryLogsResponse) {}
rpc GetRollout(GetRolloutRequest) returns (GetRolloutResponse) {}

// User role and permission management

rpc GetTeamRoles(GetTeamRolesRequest) returns (GetTeamRolesResponse) {}
rpc UpsertTeamRole(UpsertTeamRoleRequest) returns (UpsertTeamRoleResponse) {}
rpc DeleteTeamRole(DeleteTeamRoleRequest) returns (DeleteTeamRoleResponse) {}

rpc GetUserRoles(GetUserRolesRequest) returns (GetUserRolesResponse) {}

rpc GetRoleUsers(GetRoleUsersRequest) returns (GetRoleUsersResponse) {}
// Creates and deletes role assignments accordingly given a list of usernames
rpc AddUsersToRole(AddUsersToRoleRequest) returns (AddUsersToRoleResponse) {}
rpc RemoveUsersFromRole(RemoveUsersFromRoleRequest) returns (RemoveUsersFromRoleResponse) {}

rpc GetRolePermissions(GetRolePermissionsRequest) returns (GetRolePermissionsResponse) {}
rpc UpsertRolePermission(UpsertRolePermissionRequest) returns (UpsertRolePermissionResponse) {}
rpc DeleteRolePermission(DeleteRolePermissionRequest) returns (DeleteRolePermissionResponse) {}

// Query "merged" permissions a user through all of their roles
rpc GetUserPermissions(GetUserPermissionsRequest) returns (GetUserPermissionsResponse) {}

// Query which roles have what level of access on a specific resource
rpc GetResourcePermissions(GetResourcePermissionsRequest) returns (GetResourcePermissionsResponse) {}
}

message GetUserGitHubReposRequest {
Expand Down Expand Up @@ -949,3 +972,134 @@ message Rollout {
message GetRolloutResponse {
Rollout rollout = 1;
}

message Role {
string name = 1;
string team_name = 2;
string description = 3;
}

enum PermissionLevel {
PERMISSION_LEVEL_UNSPECIFIED = 0;
PERMISSION_LEVEL_READ = 1;
PERMISSION_LEVEL_UPDATE = 2;
PERMISSION_LEVEL_MANAGE = 3;
PERMISSION_LEVEL_ADMIN = 4;
}

message Permission {
string resource_path = 1;
string role_name = 2;
PermissionLevel level = 3;
}

message GetTeamRolesRequest {
string team_name = 1;
}

message GetTeamRolesResponse {
repeated Role roles = 1;
}

message UpsertTeamRoleRequest {
string team_name = 1;
// Role name to identify current role or create new role with if one does not exist.
string role_name = 2;
// Can contain an updated role name.
// If inserting, role_name and name of updated_role should match.
// Team name in this object will be ignored.
Role updated_role = 3;
}

message UpsertTeamRoleResponse {
Role role = 1;
}

message DeleteTeamRoleRequest {
string team_name = 1;
string role_name = 2;
}

message DeleteTeamRoleResponse {}

message GetUserRolesRequest {
string username = 1;
string team_name = 2;
Comment on lines +1026 to +1027
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the intent to view roles for other users?

if this is for the authenticated user, these two params are embedded in the auth object (as part of the JWT)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I thought about that. The primary use case for this request was for users to see their own roles like you said, but I figured we might as well leave it open if we end up wanting UI for a team manager viewing individual members' roles. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it might be useful to view someone else's role, so username is valid.

}

message GetUserRolesResponse {
repeated Role roles = 1;
}

message GetRoleUsersRequest {
string team_name = 1;
string role_name = 2;
}

message GetRoleUsersResponse {
repeated string usernames = 1;
}

message AddUsersToRoleRequest {
string team_name = 1;
string role_name = 2;
repeated string usernames = 3;
}

message AddUsersToRoleResponse {}

message RemoveUsersFromRoleRequest {
string team_name = 1;
string role_name = 2;
repeated string usernames = 3;
}

message RemoveUsersFromRoleResponse {}

message GetRolePermissionsRequest {
string team_name = 1;
string role_name = 2;
}

message GetRolePermissionsResponse {
repeated Permission permissions = 1;
}

message UpsertRolePermissionRequest {
string team_name = 1;
string role_name = 2;
string resource_path = 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm curious if you're weighing the options around how to represent resource path in protobuf. I could imagine it as a decomposed struct, or a tree, instead of a raw string here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall reasoning mostly came down to simplicity - the aspect that would benefit the most from managing a full tree is keeping track of a role or a user's set of permissions. So the tree or struct representations might make sense in responses. But in requests, we never need to handle more than a single path at once, so I figured strings would be good enough for the API methods.

PermissionLevel permission_level = 4;
}

message UpsertRolePermissionResponse {
Permission permission = 1;
}

message DeleteRolePermissionRequest {
string team_name = 1;
string role_name = 2;
string resource_path = 3;
}

message DeleteRolePermissionResponse {}

message GetUserPermissionsRequest {
string username = 1;
string team_name = 2;
}

message GetUserPermissionsResponse {
repeated Permission permissions = 1;
}

message GetResourcePermissionsRequest {
string resource_path = 1;
string team_name = 2;
}

message GetResourcePermissionsResponse {
// If resource path does not match the one provided in the request,
// it means that the role has transitive access via the returned path.
repeated Permission permissions = 1;
}