Gitlab protected branch restrictions for administrators access-level 60

Hello!
I am trying to configure Gitlab protected branch restrictions by reading up on the API documentation here: https://docs.gitlab.com/ee/api/protected_branches.html

Access level 60 - Administrator - is an option listed. However, when I try to send an API call to allow the branch only to be pushed by admin, it gives me an error.

Call I’m using directly from that page, except with access level 60:
curl --request POST --header "PRIVATE-TOKEN: token-here" 'https://company.gitlab/api/v4/projects/329/protected_branches?name=master&push_access_level=60&merge_access_level=60&unprotect_access_level=60'

The response:
{"error":"push_access_level does not have a valid value, merge_access_level does not have a valid value"}

My company uses the free version of Gitlab. Thank you!
Em

Hi,

to rule out other errors - does it work when you set the value to 40 or something else in the list?

Cheers,
Michael

Good morning @dnsmichi ,

I’ve tried other permission numbers (30, 40, …) and they work fine with that same command. I’m also trying via Postman and they work there, 50 (owner) and 60 (admin) aren’t recognized as valid values. This is the community edition, does that have something to do with it?

The API says that these should work:
0 => No access 30 => Developer access 40 => Maintainer access 60 => Admin access
The numbers 0, 30, and 40 work with these calls.

Thank you for your help!
Em

Hi,

maybe this is a permission issue, so that the private token you are using for the calls does not belong to an administrative account and as such, the action is denied? Please double check that :slight_smile:

Cheers,
Michael

Hi!

I’m using a private token from an administrative account (I’m a Gitlab admin). Thank you!

Best,
Em

Hi,

hm, that’s strange. I’ve grepped the source code for this error string and couldn’t find it. Which version of GitLab CE are you using? You can access that with <gitlabhost>/help in your browser.

Cheers,
Michael

Looks like we’re using GitLab Community Edition 12.4.1.

Best,
Em

Hi,

ok now you got me addicted, I’ll try hacking that up with gitlab.com and the Python API client.
Example: https://gitlab.com/dnsmichi/api-playground/blob/master/python/protected_branches.py

#!/usr/bin/env python

import gitlab

PROJECT_ID=15013654

gl = gitlab.Gitlab.from_config('gitlab.com', ['/Users/michi/.python-gitlab.cfg'])
project = gl.projects.get(PROJECT_ID)

# https://python-gitlab.readthedocs.io/en/stable/gl_objects/protected_branches.html
print("Protected branches")
p_branches = project.protectedbranches.list()
print(p_branches)

print("Protected branch: master")
p_branch = project.protectedbranches.get('master')
print(p_branch)

protect_me = "123"
p = None
# https://python-gitlab.readthedocs.io/en/stable/gl_objects/access_requests.html?highlight=developer_access#access-requests
try:
    p = project.protectedbranches.get(protect_me)
except:
    pass

if not p:
    p = project.protectedbranches.create({
        'name': protect_me,
        #'merge_access_level': gitlab.DEVELOPER_ACCESS,
        'merge_access_level': 60,
        'push_access_level': 60
    })
print(p)

With that, it works. So maybe this is fixed in 12.5.5 already.

<class 'gitlab.v4.objects.ProjectProtectedBranch'> => {u'unprotect_access_levels': [{u'access_level': 40, u'group_id': None, u'user_id': None, u'access_level_description': u'Maintainers'}], u'push_access_levels': [{u'access_level': 60, u'group_id': None, u'user_id': None, u'access_level_description': None}], u'code_owner_approval_required': False, u'merge_access_levels': [{u'access_level': 60, u'group_id': None, u'user_id': None, u'access_level_description': None}], u'name': u'123'}

Well, it doesn’t the python client somehow eats the errors.

Research

https://docs.gitlab.com/ee/api/access_requests.html says that the level can be 40 max, and for groups you can raise that to owners being 50. But not 60.

Let’s try 50, likewise this snippet:

    p = project.protectedbranches.create({
        'name': protect_me,
        'merge_access_level': gitlab.DEVELOPER_ACCESS,
        'push_access_level': gitlab.OWNER_ACCESS
    })

Now I get the same error like you.

Traceback (most recent call last):
  File "protected_branches.py", line 31, in <module>
    'push_access_level': gitlab.OWNER_ACCESS
  File "/usr/local/lib/python2.7/site-packages/gitlab/exceptions.py", line 269, in wrapped_f
    raise error(e.error_message, e.response_code, e.response_body)
gitlab.exceptions.GitlabCreateError: 400: push_access_level does not have a valid value

Considering that OWNER_ACCESS is somehow reserved for groups, but doesn’t work for protected branches … now I am really confused.

0  => No access
30 => Developer access
40 => Maintainer access
60 => Admin access
10 => Guest access
20 => Reporter access
30 => Developer access
40 => Maintainer access
50 => Owner access # Only valid for groups

Going back to 60, it eats that but it has no effect then.

Interface options

The settings do not offer admin access, so I’d say that simply is not implemented and the documentation is not uptodate in this regard. Or I am missing something.

I’m the owner of that repository, and I can only limit that like this:

Maybe “noone” has the same effect?

Let’s reverse engineer that. Google Chrome’s web console is my friend.

Next try

    p = project.protectedbranches.create({
        'name': protect_me,
        'merge_access_level': 0,
        'push_access_level': 0
    })
<class 'gitlab.v4.objects.ProjectProtectedBranch'> => {u'unprotect_access_levels': [{u'access_level': 40, u'group_id': None, u'user_id': None, u'access_level_description': u'Maintainers'}], u'push_access_levels': [{u'access_level': 0, u'group_id': None, u'user_id': None, u'access_level_description': u'No one'}], u'code_owner_approval_required': False, u'merge_access_levels': [{u'access_level': 0, u'group_id': None, u'user_id': None, u'access_level_description': u'No one'}], u'name': u'*-support'}

That seemed to work.

Since I am the owner of that project, I still should be able to push there.

Let’s try this.

Owner can still push?

Yep yep.

Conclusion

I’d say you need to re-think your strategy with limiting access here. It is not the “admin” role which grants access to protected branches and removes that permission from other roles.

Instead you’ll pick “0 = no one” and still have the owner permissions. Something else won’t work to my knowledge.

If you fear that owners take advantage of this setting, you can create a cronjob which always resets this to 0 every 5 seconds or so. I’ve recently suggested that to a customer.

Cheers,
Michael

Wow! Thank you so much for looking into this! I followed along on my own console and see what you’re talking about. I thought that the ability to see Administrators on the UI might’ve been restricted due to CE vs. Enterprise, as I know they offer more options via the API for protected branches (users, groups…). So the API call itself to anything above 40 just doesn’t work, I’m getting that as I try to push 50 or 60 (same error that it’s not valid).

I tried to set the settings to “no one” but it’s not letting me push to the repository, despite being the owner of the project and entering these same credentials when it’s asking me to push (username/password). We do run our own private instead of Gitlab CE, but I’m able to git clone/pull without any issues and the same credentials. It seems like even as the Owner, if this is set to “no one” I cannot push, but I see that you can on your instance… Gitlab projects can only have

Trying to add anything after cloning:

Permission for the master branch i’m pushing to in Gitlab:

My permissions as owner:

If I unprotect the branch and push to the repo, it works. Perhaps I can unprotect when I know I have to push and then protect it right after, like you said with a cronjob or something. I haven’t tried the Enterprise edition but adding users via the API there might work too, I’m a bit hesitant considering the documentation on the API that I’ve come across so far lol

Thank you!
Em

Hi,

seems we both have a good learning curve here :slight_smile: I’m unfortunately busy the next two days, but I do have it on my list to try that with a CE setup. Right on I was just using gitlab.com for the sake of being easy access.

I’d say, after the holidays … Meanwhile you could try to use the Python API for example, or setup an EE project and compare it with your requests.

Cheers,
Michael