Skip to content
GitmoapdocsBeta
Concept· Why does it work like that?Draft

Listing isolation

Overview

A listing returns only the rows you are allowed to see. When it gathers rows from many repositories or groups at once — every merge request across an organization, the work assigned to you everywhere, a search — each row is checked on its own, so a listing never reveals a private repository you cannot open.

That is why two people can read the same URL and get different rows, and why a count on a listing is a count of what you can see, not of what exists.

How it works

Visibility decides who can see a resource

Every group and repository has one of three visibilities:

VisibilityWho can read it
Publicanyone, including a request with no credentials
Internalanyone signed in to Gitmoap, from any organization
Privateits members, at Reporter or above

A repository or subgroup can never be more visible than the group above it. Public and internal are deliberate acts of publication; private content never crosses from one organization to another, although one person may belong to several.

A private resource you are not a member of answers 404 Not Found, never 403. Answering differently for "does not exist" and "exists, but not for you" would tell anyone guessing names which private repositories exist, so the two get the same answer.

Two kinds of listing

The API reference marks every listing with one of two kinds, and the difference is where its rows come from.

single_or_self_scoped — every row belongs to something the request already proved you can see. That is one of three things:

  • the one resource the URL names — a repository's branches, a group's members — so the check made on that resource covers every row;
  • your own data — your access tokens, your connected apps, your teams;
  • a catalogue that carries its own filter, such as file templates or the provider marketplace.

A listing that also shows settings inherited from the groups above — a repository's branch rules with inherited=true — still belongs here, because those settings already govern the resource you asked about.

cross_resource_filtered — the rows come from resources the URL does not name, so being allowed to read the container is not enough. Each row is filtered by whether you can see the repository or group it belongs to before it is returned. Examples:

ListingWhere its rows come from
A group's merge requests or work itemsevery repository beneath the group
Your review requests, your assigned work, your attention inboxevery repository where something names you
Search, at any levelevery repository and group in reach
The repository and group listingsthe whole platform
A group's or a person's activityeverything that happened in reach

What follows from this

A public group can hold private repositories. Listing that group's merge requests shows rows only from the repositories you can open; the others are not hidden behind a placeholder, they are simply absent.

A token narrows this further, never wider: a listing read with a token is still bounded by the token's scopes, and by its owner's access to each row's repository.

Rows you cannot see are left out entirely; nothing marks where they would have been. Pagination explains how to read a listing to its end.

  • Groupssetting visibility, and why a child cannot be more visible than its parent
  • Accesswho can reach what, and explaining a person's access to one resource
  • Searchthe cross-resource listing people use most
  • Paginationreading a listing to its end
  • Errorsthe 404 a private resource answers