Restrict/audit admin access to a repo

Hi,
We use gitlab on-premise, EE, Premium tier.
We would like for a specific group/repository, to restrict access so that not even admin can see the code (security team).
This thread

suggests that is not possible (and in my reading Admin mode only requires to elevate privileges, but the malicious case still persists)
A second alternative would be to at least audit when some admin accesses code in the specified repository, so that security can act on the audit.
But I don’t see that as an auditable event

The third alternative would be to go to the actual logs, to parse access to that repo, but it doesn’t seem right.
Am I missing some obvious answer?

As you have purchased EE Premium tier, you would be better asking Gitlab directly: https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=426148

This forum is mostly for Gitlab community members that don’t have paid support contracts like yourself. You are more likely to get a definitive and quicker reply from Gitlab employees that would be able to answer your question.

Admin users have access to everything, so about the only way you are going to be able to resolve it is with either the audit events, which you have access to since you have premium purchased subscription. Failing that, logs, which since they only exist locally on the server, in that sense you would be better configuring sending the logs to a remote server, like Splunk, Graylog, Kibana/Elasticsearch and using Splunk/Graylog/Kibana to search through the logs for such access if it was breached. But that is something you would have to look into once you start receiving those types of logs, and then do testing by accessing the code as an admin and then searching the logs to find and report on it. There aren’t any examples on how to do this, so it will be your own trial and error. But better would be open the support ticket with Gitlab employees to confirm everything if it’s possible or not.

If an admin has access to the server, then he has access to the logs locally and could therefore edit and remove those logs to cover his tracks. Hence using a solution like Splunk/Graylog/Kibana for searching the logs is a far more secure option to also take into account as well as the audit events.

If the audit events don’t get you what you need when you contact Gitlab support directly, then you could always ask Gitlab to make such an option available. That is why it’s better for you to contact Gitlab directly since you have paid premium support.

As a community member I like paying customers (and I did so when we had a “starter” license, and we probably still would if the company hadn’t scrapped that) asking questions here. (Almost) every answer here has value for everybody (even though you say access to audit logs are only for paying customers, just knowing that has value for everybody).

3 Likes

One other option would be to spin up another gitlab instance and keep restricted stuff there

Hi,

The forum is for everyone in the wider community. Users, customers, interested folks, learners, team members, contributors, etc. - everyone can contribute. We appreciate everyone dedicating their time to help with problems, bugs, feature ideas, architecture challenges, and more :slight_smile:

If you need priority support as a GitLab customer, you can open a support ticket for technical support. Tip: Link back to the public forum topic, and ask support engineers to answer in public. This helps with transparency, and provides help for everyone in the community in the long term. Sometimes we will make the suggestion to open a support ticket, for example when sensitive data about the architecture, settings, etc. is required which cannot be redacted and shared in public.

GitLab team members are actively engaged in responding to questions on the forum platform, but there is no guarantee for timely answers. I for example enjoy chiming into technical challenges, or scenarios that are hard to debug, or provide an opportunity to learn about GitLab features I have not used yet. Though, weeks are sometimes super busy, and my activities on the forum drop. And that’s ok - everyone contributes to helping each other as much as they prefer doing. Mental health and taking breaks is important, and avoids burning out from technology everywhere all the time.

For potential regressions or product bugs that need attention, breaking production, you can @ mention me and staff members (please do not abuse this - too much usage will lead to alert fatigue). For regressions, and bugs, it is recommended to go with bias for action and raise a bug report on GitLab.org / GitLab · GitLab when it sounds like an error, or HTTP 500 server exceptions are involved. Note: Forum staff team members cannot help with account problems on GitLab.com SaaS and anything that needs support teams to have a look at.

As part of the Developer Relations team, we are maintaining the forum, documented in the handbook Forum workflow | GitLab If we can improve workflows and engagements, let us know your ideas (best in a new topic in the Community category, or by opening an issue in the Dev Evangelism project). cc @sugaroverflow

Appreciate you sharing this. :heart:

3 Likes

I assume when you mention security team, that security bug reports and fixes should only be visible to this team first, which includes incident response handling, CVE assignment, etc. The team’s responsibility can also include a security release with picking all security patches into a newly tagged release. The delivery team at GitLab documents the process in general/security/mirrors.md · master · GitLab.org / release / GitLab Release Docs · GitLab which could be helpful as an example.

suggests that is not possible (and in my reading Admin mode only requires to elevate privileges, but the malicious case still persists)

Limiting the admin role to the security team, and 1-2 trusted peers, together with temporary admin mode mentioned in In Git Lab, how to limit admin user to access all project? - #3 by wangpeng20150512) could be an option. The restricted group does not have any other owner, maintainer, developer, reporter roles assigned.

A second alternative would be to at least audit when some admin accesses code in the specified repository, so that security can act on the audit.
But I don’t see that as an auditable event

I can see that repository_download_operation and repository_git_operation are documented as audit event types, linked from the audit events available types.

For a quick test, I tried downloading the source code from everyonecancontribute / web / everyonecancontribute.dev · GitLab and inspected Secure > Audit events in the side menu (this group has an Ultimate license, part of the Open Source program).

The Audit Events API endpoint allows for programmatic checks. I have written a short Python script based on the blog post examples in

which retrieves all audit events and dumps them in a readable JSON format. Feel free to reuse, the source code is MIT licensed in get_audit_events.py · main · Developer Evangelism and Technical Marketing at GitLab / use-cases / GitLab API / GitLab API with Python · GitLab

#!/usr/bin/env python

# Description: Fetch audit events (all, group, project)
# Requirements: python-gitlab Python libraries. GitLab API read access, and maintainer access to all configured groups/projects.
# Author: Michael Friedrich <mfriedrich@gitlab.com>
# License: MIT, (c) 2023-present GitLab B.V.

import gitlab
import os
import sys
import json

GITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')
GITLAB_TOKEN = os.environ.get('GL_TOKEN') # token requires maintainer permissions
PROJECT_ID = os.environ.get('GL_PROJECT_ID') #optional
GROUP_ID = os.environ.get('GL_GROUP_ID') #optional

#################
# Main

if __name__ == "__main__":
    if not GITLAB_TOKEN:
        print("🤔 Please set the GL_TOKEN env variable.")
        sys.exit(1)

    gl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN)

    print("# Starting...", end="", flush=True)

    # Collect all projects, or prefer projects from a group id, or a project id
    projects = []

    # Direct project ID
    if PROJECT_ID:
        projects.append(gl.projects.get(PROJECT_ID))

    # Groups and projects inside
    elif GROUP_ID:
        group = gl.groups.get(GROUP_ID)

        for project in group.projects.list(include_subgroups=True, all=True):
            print(".", end="", flush=True) # Get some feedback that it is still looping
            # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples
            manageable_project = gl.projects.get(project.id , lazy=True)
            projects.append(manageable_project)

    # All projects on the instance (may take a while to process)
    else:
        projects = gl.projects.list(get_all=True)

    print(f"\n# Found {len(projects)} projects. Analysing...", end="", flush=True) # new line

    events = {}

    # Loop over projects, fetch audit events 
    for project in projects:
            # https://python-gitlab.readthedocs.io/en/stable/gl_objects/ci_lint.html
            project_obj = gl.projects.get(project.id)
            project_name = project_obj.name
            project_web_url =project_obj.web_url

            for event in project_obj.audit_events.list():
                event_obj = project_obj.audit_events.get(event.id)
                event_entity_type = event_obj.entity_type
                event_entity_id = event_obj.entity_id
                event_details = event_obj.details
                event_created_at = event_obj.created_at

                print(event_entity_id, event_entity_type, event_created_at, end="\n\n", flush=True)
                print(json.dumps(event_details, indent=4), end="", flush=True)

    print("\nDone")

Execute the script:

export GL_TOKEN=xxx
export GL_PROJECT_ID=xxx

python3 get_audit_events.py 

Example in VS Code terminal:

The script also works with GL_GROUP_ID or instance wide (not sure if that is a good idea, untested).

Hope this gets you started. If you need more technical support in your environment, suggest opening a support ticket and link this forum topic in the message.

The third alternative would be to go to the actual logs, to parse access to that repo, but it doesn’t seem right.

If you want to go that route, suggest collecting and ingesting the logs before sending them to Elasticsearch or a different log aggregation system. The production log is available as structured JSON and can be consumed by the Elastic Agent, Splunk, etc. more easily than plaintext logs.

Am I missing some obvious answer?

If the projects should be really closed down with restricted access, a secondary GitLab instance can be an option. This requires more maintenance and setup though.