Skip to content

Commit

Permalink
Add authorization relations in proto
Browse files Browse the repository at this point in the history
  • Loading branch information
eleftherias committed Jan 30, 2024
1 parent 26db995 commit 3bb279b
Show file tree
Hide file tree
Showing 9 changed files with 2,207 additions and 1,735 deletions.
62 changes: 60 additions & 2 deletions docs/docs/ref/proto.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion internal/authz/model/minder.fga
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ type project
define profile_get: viewer
define profile_create: editor or policy_writer
define profile_update: editor or policy_writer
define profile_delete: editor or policy_writer
define profile_delete: editor or policy_writer

define profile_status_get: viewer
2 changes: 1 addition & 1 deletion internal/authz/model/minder.generated.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"schema_version":"1.1","type_definitions":[{"type":"user"},{"metadata":{"relations":{"admin":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"member":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]}}},"relations":{"admin":{"this":{}},"member":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"admin"}}]}}},"type":"group"},{"metadata":{"relations":{"admin":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"artifact_create":{},"artifact_delete":{},"artifact_get":{},"artifact_update":{},"create":{},"delete":{},"editor":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"get":{},"parent":{"directly_related_user_types":[{"type":"project"}]},"permissions_manager":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"policy_writer":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"pr_create":{},"pr_delete":{},"pr_get":{},"pr_update":{},"profile_create":{},"profile_delete":{},"profile_get":{},"profile_update":{},"provider_create":{},"provider_delete":{},"provider_get":{},"provider_update":{},"repo_create":{},"repo_delete":{},"repo_get":{},"repo_update":{},"role_assignment_create":{},"role_assignment_list":{},"role_assignment_remove":{},"role_list":{},"rule_type_create":{},"rule_type_delete":{},"rule_type_get":{},"rule_type_update":{},"update":{},"viewer":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]}}},"relations":{"admin":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"admin"},"tupleset":{"relation":"parent"}}}]}},"artifact_create":{"computedUserset":{"relation":"editor"}},"artifact_delete":{"computedUserset":{"relation":"editor"}},"artifact_get":{"computedUserset":{"relation":"viewer"}},"artifact_update":{"computedUserset":{"relation":"editor"}},"create":{"computedUserset":{"relation":"admin"}},"delete":{"computedUserset":{"relation":"admin"}},"editor":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"admin"}},{"tupleToUserset":{"computedUserset":{"relation":"editor"},"tupleset":{"relation":"parent"}}}]}},"get":{"computedUserset":{"relation":"viewer"}},"parent":{"this":{}},"permissions_manager":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"permissions_manager"},"tupleset":{"relation":"parent"}}}]}},"policy_writer":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"policy_writer"},"tupleset":{"relation":"parent"}}}]}},"pr_create":{"computedUserset":{"relation":"editor"}},"pr_delete":{"computedUserset":{"relation":"editor"}},"pr_get":{"computedUserset":{"relation":"viewer"}},"pr_update":{"computedUserset":{"relation":"editor"}},"profile_create":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"profile_delete":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"profile_get":{"computedUserset":{"relation":"viewer"}},"profile_update":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"provider_create":{"computedUserset":{"relation":"admin"}},"provider_delete":{"computedUserset":{"relation":"admin"}},"provider_get":{"computedUserset":{"relation":"viewer"}},"provider_update":{"computedUserset":{"relation":"admin"}},"repo_create":{"computedUserset":{"relation":"editor"}},"repo_delete":{"computedUserset":{"relation":"editor"}},"repo_get":{"computedUserset":{"relation":"viewer"}},"repo_update":{"computedUserset":{"relation":"editor"}},"role_assignment_create":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_assignment_list":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_assignment_remove":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_list":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"rule_type_create":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"rule_type_delete":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"rule_type_get":{"computedUserset":{"relation":"viewer"}},"rule_type_update":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"update":{"computedUserset":{"relation":"admin"}},"viewer":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"editor"}},{"tupleToUserset":{"computedUserset":{"relation":"viewer"},"tupleset":{"relation":"parent"}}}]}}},"type":"project"}]}
{"schema_version":"1.1","type_definitions":[{"type":"user"},{"metadata":{"relations":{"admin":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"member":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]}}},"relations":{"admin":{"this":{}},"member":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"admin"}}]}}},"type":"group"},{"metadata":{"relations":{"admin":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"artifact_create":{},"artifact_delete":{},"artifact_get":{},"artifact_update":{},"create":{},"delete":{},"editor":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"get":{},"parent":{"directly_related_user_types":[{"type":"project"}]},"permissions_manager":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"policy_writer":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]},"pr_create":{},"pr_delete":{},"pr_get":{},"pr_update":{},"profile_create":{},"profile_delete":{},"profile_get":{},"profile_status_get":{},"profile_update":{},"provider_create":{},"provider_delete":{},"provider_get":{},"provider_update":{},"repo_create":{},"repo_delete":{},"repo_get":{},"repo_update":{},"role_assignment_create":{},"role_assignment_list":{},"role_assignment_remove":{},"role_list":{},"rule_type_create":{},"rule_type_delete":{},"rule_type_get":{},"rule_type_update":{},"update":{},"viewer":{"directly_related_user_types":[{"type":"user"},{"relation":"member","type":"group"}]}}},"relations":{"admin":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"admin"},"tupleset":{"relation":"parent"}}}]}},"artifact_create":{"computedUserset":{"relation":"editor"}},"artifact_delete":{"computedUserset":{"relation":"editor"}},"artifact_get":{"computedUserset":{"relation":"viewer"}},"artifact_update":{"computedUserset":{"relation":"editor"}},"create":{"computedUserset":{"relation":"admin"}},"delete":{"computedUserset":{"relation":"admin"}},"editor":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"admin"}},{"tupleToUserset":{"computedUserset":{"relation":"editor"},"tupleset":{"relation":"parent"}}}]}},"get":{"computedUserset":{"relation":"viewer"}},"parent":{"this":{}},"permissions_manager":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"permissions_manager"},"tupleset":{"relation":"parent"}}}]}},"policy_writer":{"union":{"child":[{"this":{}},{"tupleToUserset":{"computedUserset":{"relation":"policy_writer"},"tupleset":{"relation":"parent"}}}]}},"pr_create":{"computedUserset":{"relation":"editor"}},"pr_delete":{"computedUserset":{"relation":"editor"}},"pr_get":{"computedUserset":{"relation":"viewer"}},"pr_update":{"computedUserset":{"relation":"editor"}},"profile_create":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"profile_delete":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"profile_get":{"computedUserset":{"relation":"viewer"}},"profile_status_get":{"computedUserset":{"relation":"viewer"}},"profile_update":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"provider_create":{"computedUserset":{"relation":"admin"}},"provider_delete":{"computedUserset":{"relation":"admin"}},"provider_get":{"computedUserset":{"relation":"viewer"}},"provider_update":{"computedUserset":{"relation":"admin"}},"repo_create":{"computedUserset":{"relation":"editor"}},"repo_delete":{"computedUserset":{"relation":"editor"}},"repo_get":{"computedUserset":{"relation":"viewer"}},"repo_update":{"computedUserset":{"relation":"editor"}},"role_assignment_create":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_assignment_list":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_assignment_remove":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"role_list":{"union":{"child":[{"computedUserset":{"relation":"admin"}},{"computedUserset":{"relation":"permissions_manager"}}]}},"rule_type_create":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"rule_type_delete":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"rule_type_get":{"computedUserset":{"relation":"viewer"}},"rule_type_update":{"union":{"child":[{"computedUserset":{"relation":"editor"}},{"computedUserset":{"relation":"policy_writer"}}]}},"update":{"computedUserset":{"relation":"admin"}},"viewer":{"union":{"child":[{"this":{}},{"computedUserset":{"relation":"editor"}},{"tupleToUserset":{"computedUserset":{"relation":"viewer"},"tupleset":{"relation":"parent"}}}]}}},"type":"project"}]}
22 changes: 11 additions & 11 deletions internal/controlplane/handlers_authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ func lookupUserPermissions(ctx context.Context, store db.Store) auth.UserPermiss
func authorizedOnProject(ctx context.Context, projectID uuid.UUID) error {
claims := auth.GetPermissionsFromContext(ctx)
opts := getRpcOptions(ctx)
if opts.GetAuthScope() != minder.ObjectOwner_OBJECT_OWNER_PROJECT {
return status.Errorf(codes.Internal, "Called IsProjectAuthorized on non-project method, should be %v", opts.GetAuthScope())
if opts.GetTargetResource() != minder.TargetResource_TARGET_RESOURCE_PROJECT {
return status.Errorf(codes.Internal, "Called IsProjectAuthorized on non-project method, should be %v", opts.GetTargetResource())
}

// call openFGA using the relation and project ID
// opts.GetRelation()

if !slices.Contains(claims.ProjectIds, projectID) {
return util.UserVisibleError(codes.PermissionDenied, "user is not authorized to access this project")
}
Expand Down Expand Up @@ -145,7 +148,11 @@ func EntityContextProjectInterceptor(ctx context.Context, req interface{}, _ *gr

opts := getRpcOptions(ctx)

if !requiresProjectAuthorization(opts) {
if opts.GetTargetResource() == minder.TargetResource_TARGET_RESOURCE_UNSPECIFIED {
return nil, status.Error(codes.Internal, "cannot perform authorization, because target resource is unspecified")
}

if opts.GetTargetResource() != minder.TargetResource_TARGET_RESOURCE_PROJECT {
if !opts.GetNoLog() {
zerolog.Ctx(ctx).Info().Msgf("Bypassing setting up context")
}
Expand All @@ -171,7 +178,7 @@ func ProjectAuthorizationInterceptor(ctx context.Context, req interface{}, _ *gr

opts := getRpcOptions(ctx)

if !requiresProjectAuthorization(opts) {
if opts.GetTargetResource() != minder.TargetResource_TARGET_RESOURCE_PROJECT {
if !opts.GetNoLog() {
zerolog.Ctx(ctx).Info().Msgf("Bypassing project authorization")
}
Expand Down Expand Up @@ -231,13 +238,6 @@ func getProjectFromRequestOrDefault(ctx context.Context, in HasProtoContext) (uu
return permissions.ProjectIds[0], nil
}

// requiresProjectAuthorization return true if an authorization check should be performed on the requested project
func requiresProjectAuthorization(opts *minder.RpcOptions) bool {
// default to returning true, unless we explicitly specify anonymous, or a different type of authorization scope
return !opts.Anonymous &&
opts.GetAuthScope() != minder.ObjectOwner_OBJECT_OWNER_USER
}

// Permissions API
// ensure interface implementation
var _ minder.PermissionsServiceServer = (*Server)(nil)
Expand Down
Loading

0 comments on commit 3bb279b

Please sign in to comment.