Skip to content

feat: repo visibility controls — restrict push list to assigned repos and add 'my repos' filter #88

@coopernetes

Description

@coopernetes

Summary

Operators running the proxy for both open-source and commercially sensitive (e.g., joint-venture) repos need to control who can see which push records in the dashboard. Today every authenticated user sees all push history for all repos. Two related capabilities are needed:

  1. Repo-level visibility restriction: mark specific repos as private so their push records are only visible to users with an explicit permission grant (contributor or reviewer)
  2. "My repos" filter: an opt-in UI/API filter that scopes the push list to repos where the authenticated user is assigned — useful for both private deployments and large open deployments where noise is the problem

Current state

PushController.list() (GET /api/push) accepts status, project, repo, user, and search filters but has no concept of per-user visibility. Every authenticated user sees every push record. The RepoPermission store already holds the data needed to answer "which repos is this user assigned to" — RepoPermissionStore.findByUsername(username) returns all grants for a user.

PushRecord carries provider and url (the upstream repo URL), which can be compared against RepoPermission.path to determine whether a record is accessible.

Proposed approach

1. restricted flag on URL allow rules

Add a restricted: true field to RuleConfig (the YAML allow-rule entry). A restricted rule means push records for matching repos are hidden from users who have no RepoPermission grant (PUSH or APPROVE) for that repo. Unrestricted repos (the default) are visible to all authenticated users as today.

git-proxy:
  rules:
    allow:
      - slugs: [acme-jv/private-repo]
        restricted: true

This is intentionally coarse — the visibility flag lives at the rule level, not per-repo, which keeps the config surface small.

2. GET /api/push?mine=true filter

New optional filter param on PushController.list(). When mine=true and the user is authenticated:

  • Fetch all RepoPermission grants for the user via RepoPermissionService.findByUsername()
  • Filter the returned push records to those whose provider + url match at least one grant

mine=true does not imply visibility restriction — it works on both open and restricted repos. It's the "show me my work" view.

3. Visibility enforcement

When the configured rule set contains at least one restricted: true rule, PushController.list() (and getById) must enforce visibility:

  • ROLE_ADMIN bypasses visibility — always sees everything
  • Authenticated non-admin users see: all non-restricted repo pushes, plus restricted repo pushes where they have a grant
  • The set of accessible restricted paths is derived from RepoPermissionService.findByUsername(auth.getName())

The restriction check does not need to be in the DB query — post-filter in Java is acceptable for the initial implementation given typical push list sizes. A DB-level predicate is a follow-on optimisation.

4. Dashboard UI

  • Add a "My repos" toggle to the push list filter bar
  • Restricted repos that the current user cannot see should not appear in search suggestions or repo dropdowns
  • Admins should see a visual indicator that a repo is restricted (e.g. a lock icon in the push detail)

Constraints

  • The restricted flag needs to round-trip through the live config reload path (LiveConfigLoader) so operators don't need a restart to restrict/unrestrict a repo
  • RepoPermission.path uses /owner/repo convention; PushRecord.url is a full upstream URL — the visibility check needs a normalisation step to compare them (strip host prefix, strip .git suffix)
  • Org-level tagging for repos (filtering by topic/team) is a related quality-of-life improvement worth tracking as a follow-on but is out of scope here

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions