# Gitlab

Connecting GitLab gives SureCloud read access to your GitLab groups, projects, members, protected branch rules, and merge request approval settings. SureCloud monitors protected branch configuration to verify that direct pushes are restricted and that merge request approvals are required, audits group and project membership for inactive or overly privileged accounts, checks whether security scanning jobs (SAST, dependency scanning, secret detection) are present in CI/CD pipelines, and reviews project visibility settings to detect publicly exposed repositories. This provides continuous evidence that your SDLC controls are enforced at the source code level.

{% hint style="info" %}
SureCloud connects to GitLab.com using OAuth 2.0. For GitLab Self-Managed instances, a Personal Access Token scoped to a dedicated service account is used instead.
{% endhint %}

## Authentication and setup

{% tabs %}
{% tab title="GitLab.com (OAuth 2.0)" %}
{% stepper %}
{% step %}

#### Initiate the connection in SureCloud

In SureCloud, navigate to **Integrations → GitLab → Connect**. SureCloud redirects you to GitLab's OAuth authorisation page.
{% endstep %}

{% step %}

#### Authorise SureCloud in GitLab

Review the requested scopes and click **Authorise**. The OAuth application is pre-registered by SureCloud — you do not need to create an application in GitLab.

SureCloud requests the following OAuth scopes:

| Scope             | Purpose                                                                                       |
| ----------------- | --------------------------------------------------------------------------------------------- |
| `read_api`        | Read all resources accessible via the GitLab REST API including projects, groups, and members |
| `read_user`       | Read the authorising user's profile and group memberships                                     |
| `read_repository` | Read repository content metadata (used for pipeline configuration inspection)                 |

{% hint style="warning" %}
The authorising account must be a **group Owner** to read group-level member lists, audit events, and all project settings within the group. Accounts with Developer or Maintainer roles will have partial visibility only.
{% endhint %}
{% endstep %}

{% step %}

#### Select groups to monitor

After authorisation, return to SureCloud and select the GitLab top-level groups you want to monitor. SureCloud will collect data from all subgroups and projects nested within the selected groups.

Click **Save Connection**.
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="GitLab Self-Managed (Personal Access Token)" %}
{% stepper %}
{% step %}

#### Create a dedicated service account

In your GitLab Self-Managed instance, create a service account user (e.g. `surecloud-ccm`). Assign the account the **Owner** role on each top-level group you want SureCloud to monitor — this is required to read group membership and all project settings.

For instances running GitLab 16.1 or later, use the GitLab **Service Accounts** feature (**Admin → Users → Service Accounts → New service account**) rather than a standard user account.
{% endstep %}

{% step %}

#### Generate a Personal Access Token

Log in as the `surecloud-ccm` account (or use the Admin API to generate a token for a service account) and navigate to **User Settings → Access Tokens → Add new token**.

Select the following scopes:

| Scope             | Purpose                                          |
| ----------------- | ------------------------------------------------ |
| `read_api`        | Read all API-accessible resources                |
| `read_repository` | Read repository metadata for pipeline inspection |

Set an expiry date of up to 365 days. Copy the token immediately.

{% hint style="warning" %}
Rotate this token before its expiry and update it in **SureCloud → Integrations → GitLab → Edit Connection** to avoid a data collection gap.
{% endhint %}
{% endstep %}

{% step %}

#### Enter credentials in SureCloud

In SureCloud, navigate to **Integrations → GitLab → Connect (Self-Managed)** and provide:

* **GitLab instance URL** (e.g. `https://gitlab.yourcompany.com`)
* **Personal Access Token**

Click **Test Connection**, then **Save**.
{% endstep %}
{% endstepper %}
{% endtab %}
{% endtabs %}

## Endpoints

| API Call                                       | Use Case                                                                                  |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `GET /api/v4/groups`                           | Enumerate top-level groups and subgroups                                                  |
| `GET /api/v4/groups/{id}/members/all`          | List all direct and inherited group members with their access levels                      |
| `GET /api/v4/groups/{id}/projects`             | Enumerate all projects within a group including visibility and access settings            |
| `GET /api/v4/projects/{id}`                    | Read full project configuration including visibility level, fork policy, and merge method |
| `GET /api/v4/projects/{id}/protected_branches` | Read protected branch rules; verify push and merge restrictions                           |
| `GET /api/v4/projects/{id}/approval_rules`     | Read merge request approval rules and minimum approver count                              |
| `GET /api/v4/projects/{id}/members/all`        | List all project members and their access levels                                          |
| `GET /api/v4/projects/{id}/audit_events`       | Read project-level audit events for access and settings changes                           |
| `GET /api/v4/groups/{id}/audit_events`         | Read group-level audit events                                                             |
| `GET /api/v4/projects/{id}/.gitlab-ci.yml`     | Read CI/CD pipeline configuration to detect security scanning job presence                |

## Pagination

The GitLab REST API uses page-based pagination via `page` and `per_page` query parameters. The total page count is returned in the `X-Total-Pages` response header and the next page URL in the `Link` header. SureCloud increments the `page` parameter until it exceeds `X-Total-Pages`.

```
X-Total: 1284
X-Total-Pages: 13
X-Per-Page: 100
X-Page: 1
Link: <https://gitlab.com/api/v4/groups/123/projects?page=2&per_page=100>; rel="next"
```

SureCloud requests up to 100 results per page using `per_page=100`.

## Required permissions

For GitLab.com (OAuth), the authorising account must have the **Owner** role on each top-level group to read all member lists, audit events, and project settings within that group.

For GitLab Self-Managed (Personal Access Token), the `surecloud-ccm` account must have the **Owner** role on each monitored group. The `read_api` scope on the token is required for all endpoints. The `read_repository` scope is required for CI/CD pipeline configuration inspection.

{% hint style="info" %}
GitLab audit events are only available on GitLab **Premium and Ultimate** tiers (both GitLab.com and Self-Managed). On the Free tier, audit event endpoints will return empty results — all other data collection is unaffected.
{% endhint %}

## Polling frequency

| Data type                    | Collection interval |
| ---------------------------- | ------------------- |
| Group and project inventory  | 24 hours            |
| Member access levels         | 24 hours            |
| Protected branch rules       | 24 hours            |
| Merge request approval rules | 24 hours            |
| Project visibility settings  | 24 hours            |
| Audit events                 | 6 hours             |

## Troubleshooting

<details>

<summary>Protected branch rules are missing for some projects</summary>

Protected branch data is accessible to users with at least the **Maintainer** role on the project. If the SureCloud account has Developer access only on some projects, those projects' protected branch data will not be returned.

Confirm the service account or authorising user has **Owner** or **Maintainer** access on all target projects. At the group level, assigning **Owner** propagates to all projects within the group.

</details>

<details>

<summary>Merge request approval rules are returning as empty</summary>

Merge request approval rules are a **Premium and Ultimate** tier feature on GitLab.com and GitLab Self-Managed. On the Free tier, the `/approval_rules` endpoint returns an empty list. SureCloud will reflect this as no approval rules configured, which is accurate for Free-tier projects.

If your instance is on a paid tier and approval rules are still missing, confirm the project has approval rules defined in **Project → Settings → Merge requests → Approval rules**.

</details>

<details>

<summary>Audit events are not appearing for any groups or projects</summary>

Audit events require the **Premium or Ultimate** GitLab tier. On the Free tier, the audit events endpoint returns a 404 or empty response. SureCloud skips audit event collection for groups and projects where the endpoint is unavailable.

If your instance is on a paid tier, confirm the authorising account has the **Owner** role — Maintainer and below cannot access audit event logs.

</details>

<details>

<summary>Subgroups and their projects are not appearing</summary>

SureCloud uses `GET /api/v4/groups/{id}/projects` with the `include_subgroups=true` parameter to traverse nested subgroups. If subgroup projects are missing, confirm the top-level group ID is correctly entered in SureCloud and that the service account has **Owner** access on the top-level group (which cascades to all subgroups).

</details>

<a href="https://docs.gitlab.com/ee/api/rest/" class="button secondary">GitLab REST API reference</a> <a href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html" class="button secondary">GitLab Personal Access Token documentation</a>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://surecloud.gitbook.io/surecloud-docs/integrations/ccm-and-evidence-collection-integrations/gitlab.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
