Members, roles, permissions, visibility
Intermediate GitLab UI
Why this matters
Half the "Git is not working" messages a team receives are permission problems wearing a Git costume: a push refused, a merge button greyed out, a project that appears not to exist. Knowing the ladder tells you instantly whether you are looking at a Git problem or an access problem, which are solved by very different people.
The ladder
| Role | What it adds to the one below |
|---|---|
| Guest | View and comment on issues. On a private project, no access to the repository at all |
| Planner | Manage issues, epics, milestones and iterations (added in GitLab 17.7) |
| Reporter | Read the code, browse history, run reports and view pipelines |
| Developer | Push branches, open merge requests, run pipelines |
| Maintainer | Merge into protected branches, change project settings, add members |
| Owner | Delete the project, change its visibility, transfer it |
There is also a Security Manager role, in beta, for people who manage vulnerabilities and compliance without needing to push code.
Two lines in that table do most of the work. Developer is where a person becomes able to contribute: branches, merge requests, pipelines. Maintainer is where they become able to change what everyone else lives with: protected branches, settings, membership. The gap between them is deliberate.
Which role should you ask for?
| If you | Ask for |
|---|---|
| Write documentation, and want to open merge requests | Developer |
| Test, and need to check out branches and file issues | Developer (or Reporter if you never push) |
| Manage the backlog and the board, and do not push | Planner |
| Read the code and comment, nothing more | Reporter |
| Own the project's branch rules and merge button | Maintainer |
The commonest mistake is asking for Maintainer because it sounds like the "proper" role. It is not a seniority badge; it is responsibility for the protected branch. Developer is the contributor's role, and asking for it gets a faster yes.
Requesting access
If you can see a project but cannot act on it, its page shows a Request Access link near the name; clicking it notifies the maintainers. If you cannot see the project at all, the URL looks like a missing page and there is nothing to click: ask a member directly.
Maintainers and Owners add people at Manage → Members → Invite members, choosing the role and, optionally, an expiry date for temporary access such as a contractor's.
The Members page is also where you find out why you have access: the Source column says "Direct member" or names the group the access comes from (lesson 9.2).
Visibility
Separate from roles, and often confused with them:
| Visibility | Who can see it |
|---|---|
| Private | Only members |
| Internal | Any signed-in user of this GitLab instance; on gitlab.com that means every user in the world, so treat it as public there |
| Public | Anyone, signed in or not |
Visibility is changed by an Owner under Settings → General → Visibility, project features, permissions. The same page turns individual features on and off, which explains occasional oddities such as a project with no Issues tab: someone disabled it.
How to do it
Roles are not a Git concept, so there is no command. What the terminal gives you is the symptom:
remote: GitLab: You are not allowed to push code to protected branches on this project.That is a Maintainer-level restriction (lesson 6.9). A different message, 403 Forbidden or a repository that appears not to exist, points at not being a member at all.
VS Code shows no role information. A push refused for permissions surfaces as a failed push with the server's message in Output → Git; read it there rather than in the truncated notification.
Same: the Push failed notification carries the server's message, and Git → Show Git Log → Console has the full text.
- Manage → Members lists everyone, their role, the source of their access and any expiry. Most roles can view this page.
- Invite members (Maintainers and Owners) adds a person or a group with a chosen role.
- Request Access, near the project name, is what you use when you can see a project but cannot act.
- Settings → General → Visibility, project features, permissions (Owners) sets private, internal or public and switches individual features on or off.
The same ladder, shorter: Read, Triage, Write, Maintain, Admin. Write is the equivalent of Developer and is what a contributor needs; Admin, not Maintain, manages branch protection. Visibility is Private, Internal (organizations on GitHub Enterprise only) and Public. See lesson 10.3.
Common mistakes
- Asking for Maintainer to avoid asking twice. It carries responsibility for the protected branch and is usually declined or slow; Developer is the contributor's role.
- Reading a private project's URL as a broken link. GitLab deliberately does not reveal that a private project exists.
- Confusing role with visibility. A public project still needs Developer to push to.
- Assuming Internal means "inside the company" on gitlab.com. It means every GitLab user.
- Granting access project by project when the person works across the group.
Try it yourself
Goal: read your own access on a real project.
- Open a project you work on and find Manage → Members.
- Find yourself: what role do you have, and does the Source column say direct or through a group?
- Check the project's visibility: the badge next to its name, or Settings → General if you can see it.
- Compare your role with the table above: can you push a branch? Can you merge into
main? - On your own practice project, where you are the Owner, look at how many more options the settings pages offer than on a project where you are a Developer.
Expected result: you can state your role, where it comes from, and one thing it does not allow you to do.
Show solution
Step 5 is the quickest way to feel the ladder: as Owner you see visibility, deletion and transfer; as Developer those pages are simply absent rather than greyed out, which is why "the setting is not there" is usually a permission answer rather than a missing feature.