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
Example:
https://gitlab.yourcompany.com
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.
Useful GitLab documentation > https://docs.gitlab.com/integration/oauth_provider/
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.
Useful GitLab documentation: https://docs.gitlab.com/user/profile/personal_access_tokens/
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
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.
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.





