Skip to main content

GitLab

This article explains how Pensero connects to GitLab, what MR data it reads, and how admins can set up and manage repositories. It also outlines the metrics Pensero derives to support delivery analysis.

Written by Wayne

Overview

Pensero integrates with GitLab to read metadata from your Merge Requests (MRs), including descriptions, comments, and workflow events. This allows Pensero to understand what work is being delivered, how it flows through reviews, and how effort turns into outcomes, without storing your code.

Pensero reads the MR diff to analyse the change, then discards it. Source code and diffs are never stored. Changed lines are kept only as one-way SHA-256 hashes, which cannot be turned back into code.

Admins can configure the GitLab integration from the Integrations section by following the steps below.

Not an admin? You can fix your own usernames: go to Data health → My data → Link more accounts. Connecting integrations and changes in Organization → Users need an admin.

What Pensero Reads from GitLab

Pensero ingests Merge Request data, including the diff, to build an accurate picture of delivery. The diff is not stored.

From each Merge Request, Pensero reads:

  • Title and MR number: Identifiers of the contribution

  • State: Open, closed, draft, locked, or merged

  • Description: Context and intent of the change

  • Key timestamps: Creation, approval, merge, and closure

  • Author: Who opened the MR

  • Source and target branches: Branches involved in the merge

  • Related tickets: When the MR is linked to an issue or task

  • Code diff: Files touched and lines changed, analysed and not stored

Pensero reads the code diff for analysis only and never stores it.

Important

Pensero requests access to all repositories, but it only reads the work of the contributors listed in your Organization Settings. Everything else is skipped.

You can limit which repositories Pensero syncs, but this can cause missing data over time.

Review the data processing rules in this link.

How Pensero Uses This Data

Merge Requests are one of the core building blocks of delivery.

Pensero combines MR metadata with related tickets, documents, and collaboration signals to understand:

  • What problem was being addressed

  • How complex the work was

  • How work moved through review and approval

Rather than counting activity, Pensero focuses on understanding delivery and workflow behavior.

From this data, Pensero derives insights such as:

  • Time to merge

  • Time to approve

  • Time to first comment

  • High-level change summaries (for Code Insights customers)

These signals help teams understand how work flows, where friction appears, and how delivery evolves over time.

How to Connect Your GitLab Repositories

Prerequisites

  • GitLab account with access to the projects you want to track

  • At least the Reporter role on those projects. Guest and Planner are not enough: they can list a private project but GitLab returns 403 when reading its repository and merge requests. Grant Reporter directly on the project, or on the parent group so every project under it inherits it.

First-Time Setup

Step 1 - Go to Integrations

Navigate to the Integrations section from the left sidebar, locate GitLab and click Connect.

Step 2 - Complete GitLab Authentication

Complete the authentication flow and authorize Pensero.

  • You must be a GitLab Group Owner to install the app.

  • Access permissions can be updated later from your GitLab App settings.

Approve the following permissions:

  • read_user: Read user profile information

  • read_api: Read-only access to the API

  • read_repository: Read repository data

Step 3 - Select Repositories

Choose the repositories you want to connect.

You must have at least the Reporter role on each repository (directly, or inherited from a parent group).

After Connecting

Pensero will begin syncing merge requests, commits, and repository metadata immediately. Initial sync may take 30 to 60 minutes depending on repository size and history.

Adding new Repositories Later

Step 1 - Go to Integrations

Open the Integrations page.

Step 2 - Click “Manage GitLab”

This opens the GitLab management panel.

Step 3 - Select Additional Repositories

Choose the new repositories you want to connect.

How to Connect GitLab On-Premises / Self-Hosted GitLab

Pensero supports connecting to self-hosted GitLab instances in addition to GitLab.com.

This guide explains how to connect your GitLab instance to Pensero using either OAuth or a personal access token.

Prerequisites

Before you begin, make sure you have:

  • A running self-hosted GitLab instance

  • A GitLab instance that is either:

    • accessible from the public internet, or

    • configured with Pensero IP allowlisting

  • A GitLab account with the required permissions on the projects you want to track:

    • At least the Reporter role (Guest and Planner cannot read a private project); grant it on the project or on the parent group

  • Access to Pensero’s Integrations page

For OAuth setup, you may also need a GitLab administrator to create an OAuth application for the instance.

Step 1 - Go to Integrations

In Pensero, navigate to:

  • Integrations → GitLab → ▾ next to Connect → Connect self-hosted instance

Make sure the URL matches the base URL of your self-hosted GitLab instance.

Step 2 - Complete Authentication

You can authenticate using either:

Option 1: Connect with OAuth

OAuth is recommended when your organization wants to authorize Pensero through a GitLab OAuth application.

Create a GitLab OAuth Application

In your self-hosted GitLab instance, go to: Admin → Applications → New application

  • Create a new application for Pensero

After the application is created, GitLab will show:

GitLab field

Enter in Pensero as

Application ID

Client ID

Secret

Client

In Pensero, select OAuth and enter:

  • GitLab instance URL

  • Client ID

  • Client secret

Then click Connect GitLab and complete the OAuth approval flow.

Option 2: Connect with a Personal Access Token

Use this option if your organization prefers token-based authentication instead of OAuth.

Create a Personal Access Token in GitLab

In GitLab, go to: User avatar → Edit profile → Access tokens

  • Create a new token for Pensero.

  • Suggested token name: Pensero Integration

Approve the following permissions:

Scope

Purpose

read_user

Read user profile information

read_api

Read-only access to the GitLab API

read_repository

Read repository data

Copy the token after creating it. GitLab may not show the token value again after you leave the page.

Step 3 - Select Repositories

After the connection is complete, choose the repositories you want Pensero to track.

In Pensero, go to: Integrations → GitLab → Manage → Search repos

Enable the repositories you want to include.

After Connecting

Pensero will begin syncing merge requests, commits, and repository metadata immediately. Initial sync may take 30 to 60 minutes depending on repository size and history.

How to Verify It Is Working

  1. Navigate to Integrations > GitLab > Manage and confirm that your GitLab projects are listed, Auto-Sync is enabled, there are no warnings, and the last sync date is recent.

  2. Run a health check from the integration card

Troubleshooting 403 Errors and Missing Merge Requests

A 403: Forbidden error means GitLab found the project but refused to let the Pensero account read it. The warning shown next to the repository in Integrations → GitLab → Manage tells you which of these two cases applies.

Case 1: The connected account has the Guest or Planner role

The warning reads: "GitLab denied access to this project: the connected account has the Planner role, but reading a private project needs at least Reporter."

Guest and Planner members can see a private project in GitLab but cannot read its repository or merge requests through the API, so commits and merge requests are never synced.

How to fix:

  • Go to the project → Manage → Members (or the parent group → Manage → Members to cover all of its projects) and raise the Pensero account to Reporter.

  • If the account is only a member of a subgroup, the role applies only to projects under that subgroup. Grant Reporter on the top-level group to cover every project in it.

  • Nothing else is needed: the next sync picks up the new role automatically.

Case 2: Merge requests are disabled on the project

The health check shows "Connected, merge requests disabled: only direct commits to the default branch are tracked", and the sync log shows a warning rather than a failure.

GitLab returns 403 on the merge requests API whenever the project has the Merge requests feature turned off, regardless of the account role. Pensero keeps syncing direct commits to the default branch, but there are no merge requests to read.

How to fix:

  • If the team does use merge requests on this project, enable them in GitLab: project → Settings → General → Visibility, project features, permissions → Merge requests.

  • If the project is a mirror or a fork and the merge requests live in another project, connect that project in Pensero instead.

  • If the project is expected to receive direct commits only, no action is needed; the warning is informational.

Troubleshooting GitLab On-Premise 404 Errors

If you're seeing 404: Not Found errors when Pensero attempts to sync with your GitLab on-premise repositories, this guide will help you diagnose and resolve the issue.

Understanding the Problem:

A 404 error means Pensero cannot locate your GitLab repositories. This typically happens due to:

  • ❌ Incorrect user permissions - The user doesn't have access to the repositories

  • ❌ Invalid/expired access token - Authentication credentials are missing required scopes

  • ❌ Wrong repository paths - Repository URLs are misconfigured

  • ❌ Network/firewall restrictions - GitLab instance is not accessible from Pensero

Step-by-Step Troubleshooting

Follow these steps in order to identify and fix the issue:

Step 1: Verify User Account Access

What to check:

The user account configured in Pensero must exist in your GitLab instance and have access to all repositories you want to sync.

How to validate:

Log into your GitLab instance with the user account configured in Pensero

Navigate to each repository that shows 404 errors

Check user's role in each repository:

Go to: Repository → Settings → Members

  • The user must have at least Reporter role

  • Guest and Planner are not enough

Validation checklist:

  • User account exists and can log into GitLab

  • User can view each repository in GitLab UI

  • User has at least the Reporter role on each repository (directly or inherited from a group)

  • User membership has not expired

How to fix:

  • Go to Repository → Settings → Members

  • Click "Invite members"

  • Add the user (e.g., [email protected])

  • Assign role: Reporter (a higher role also works, but is not needed)

  • Set expiration: "No expiration" or future date

  • Click "Invite"

Step 2: Verify Repository Paths

What to check:

Repository paths must exactly match the namespace/project structure in your GitLab instance.

How to validate:

Find the correct path in GitLab:

  • Navigate to the repository in GitLab UI

  • Look for the path under the project name

  • Format: namespace/project-name or group/subgroup/project-name

  • Example:

    • ✓ Correct: platform/client-frontend

    • ✗ Wrong: client-frontend

Compare with Pensero configuration:

  • In Pensero, check the exact repository path configured

  • Paths are case-sensitive

  • Must include the full namespace hierarchy

Expected results:

  • ✅ Success (200): Returns JSON with repository details

  • ❌ 404 Error: Repository path is wrong or user has no access

How to fix:

  • Update the repository path in Pensero to match the exact GitLab path

  • Include all parent groups/namespaces in the path

Step 3: Verify Access Token Configuration

What to check:

The GitLab access token must have the correct scopes and not be expired.

How to validate:

Locate the access token in GitLab:

  • Go to: User Settings → Access Tokens (Log in as the user configured in Pensero)

Check token status:

  • Expiration date: Not expired

  • Status: Active

  • Verify token has these scopes:

    • read_user

    • read_api

    • read_repository

How to fix (create new token):

  • Go to GitLab → User Settings → Access Tokens

  • Click "Add new token"

  • Configure:

    • Token name: Pensero Integration

    • Expiration date: Select future date or leave blank

    • Scopes: Check read_user, read_api and read_repository

    • Click "Create personal access token"

    • Copy the token immediately (you won't see it again)

    • Update the token in Pensero integration settings

Still Having Issues?

If you've completed all steps and still see 404 errors, check these advanced scenarios:

Network restrictions:

  • Is the GitLab instance behind a VPN?

  • Are there IP whitelist restrictions?

  • Does Pensero's IP need to be whitelisted?

GitLab configuration:

  • Is the API enabled in GitLab? (Admin → Settings → Network)

Repository sync settings

After connecting your code repository integration, you can manage how Pensero syncs repositories from here.

Note: Repository sync settings are only available for users with an Admin role in Pensero.

Sync options

No sync

Pensero will not automatically connect new repositories. Use this if you prefer to manage repositories manually.

New repositories only

Pensero will automatically detect and connect new repositories created after this setting is enabled.

All repositories

Pensero will sync all available repositories from your code provider, except those excluded by patterns.

When you connect repositories with All

If you select All for a group when you connect repositories, Pensero also sets the sync option to New repositories only, so new repositories connect automatically. Pensero does not change the option if it is already on, or if someone changed it before. You can change it at any time in the sync settings.

The sync option applies to all connected groups, also to groups where you chose Select repositories.

Excluded repositories

You can add patterns to exclude repositories that should not be tracked, such as test, sandbox, personal, or experimental repositories.

Patterns match the full repository path.

Examples:

  • org-x/*

  • org-x/api-*

  • group/sub/*

  • group/sub/project

The * wildcard must be at the end of the pattern.

Did this answer your question?