Skip to content
Closed
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
11 changes: 10 additions & 1 deletion app/controlplane/internal/service/group.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2025 The Chainloop Authors.
// Copyright 2025-2026 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -528,6 +528,15 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis
return nil, errors.BadRequest("invalid", fmt.Sprintf("invalid group reference: %s", err.Error()))
}

// Authorize before resolving results. This mirrors the sibling group sub-resource handlers
// (ListMembers, etc.): only org admins/owners or a maintainer of the target group may read a
// group's project attachments. The visibleProjects row filter alone is insufficient because it
// returns nil ("no filter") for callers where RBAC is not applied (e.g. a legacy RoleViewer or
// an org-scoped API token), which the data layer treats as full visibility.
if err = g.userHasPermissionOnGroupMembershipsWithPolicy(ctx, currentOrg.ID, req.GetGroupReference(), authz.PolicyGroupListMemberships); err != nil {
return nil, err
}

// Initialize the options for getting projects
groupOpts := &biz.ListProjectsByGroupOpts{
IdentityReference: &biz.IdentityReference{
Expand Down
Loading