Overview

The GitLab integration monitors your projects, branch protection rules, group membership, and security configurations. LowerPlane uses read-only API access and does not access source code contents. LowerPlane ships two separate GitLab integrations:
IntegrationUse when
GitLabYour projects live on gitlab.com
GitLab Self-ManagedYou run your own GitLab instance on your own infrastructure
Both collect the same data and run the same tests. They differ only in how authentication is set up. GitLab Cloud uses LowerPlane’s own OAuth application, while GitLab Self-Managed uses an OAuth application that you create on your instance.

Authentication

GitLab uses OAuth 2.0 for authentication. When you connect, you’ll be redirected to GitLab to authorize LowerPlane.

Required Permissions (OAuth Scopes)

ScopeWhat It GrantsWhy LowerPlane Needs It
read_apiRead access to the APIRead project metadata, branch protection rules, merge request settings, group members, and pipeline configuration
read_userRead user profileIdentify the connecting user and read member profiles for access reviews
The read_repository scope is intentionally excluded. LowerPlane does not access code contents, commits, or file trees. The read_api scope provides all the metadata needed for compliance checks.Do not grant additional scopes when creating a self-managed OAuth application. read_api and read_user are sufficient, and requesting more will show your users a broader consent screen than LowerPlane actually needs.

What LowerPlane Collects

Project Metadata

Name, visibility, default branch, CI config path, open merge request count, member count

Branch Protection

Push restrictions, required merge request approvals, force push settings

Group Members

Member list and roles for access reviews

Vulnerability Scanning

SAST pipeline configuration status and vulnerability report presence

Security Tests

LowerPlane runs 7 automated tests against your GitLab instance:
TestSeverityApplies To
Code repo should be classifiedCriticalEach project
GitLab group level MFA should be enforcedCriticalEach group
GitLab vulnerability scan should be enabledMediumEach project
Code changes should be reviewed by peers before mergingHighEach project
Merging of code changes should require passing status-checksHighEach project
Branch Protection rules should be enforcedHighEach project
GitLab access should be removed for offboarded userCriticalEach member
MFA is verified at the group level. The “GitLab group level MFA should be enforced” test requires the account you authorize with to be an Owner of the group, because GitLab only returns the require_two_factor_authentication flag to owners. If the authorizing account has a lower role, the test reports an explicit permissions reason rather than a failure.LowerPlane does not run a per-user MFA test for GitLab. GitLab exposes an individual user’s 2FA state only to instance administrators, which is never available on GitLab.com. Group-level enforcement (every member must enroll before accessing the group) is applied uniformly across GitLab Cloud and self-managed so that the evidence reads the same way for an auditor, and it is the reliable signal for SOC 2 CC6.1.

Connecting GitLab Cloud

1

Navigate to Integrations

Go to Settings > Integrations and find GitLab in the Version Control category.
2

Click Connect

Click the Connect button. You’ll be redirected to GitLab’s authorization page.
3

Authorize

Review the requested permissions and click Authorize. Use an account with group owner access.
4

Initial Sync

LowerPlane syncs your projects, members, and branch protection settings. This typically takes 1-2 minutes.

Connecting Self-Managed GitLab

If you run your own GitLab instance, use the GitLab Self-Managed integration. It authenticates against your instance’s own OAuth endpoints using an OAuth application that you create and control.

Prerequisites

Before you begin, make sure you have:
  • A self-managed GitLab instance running GitLab CE or EE.
  • Permission to create an OAuth application on that instance: either instance administrator access (Admin Area) or the ability to create a user-owned or group-owned application.
  • An account that is an Owner of the groups you want covered, so the group MFA test can read the 2FA enforcement flag.
  • Your instance reachable from LowerPlane over HTTPS, with a valid publicly trusted TLS certificate.

Step 1: Create an OAuth application in GitLab

1

Open the Applications page

Sign in to your GitLab instance and go to Admin area → Applications, then click Add new application.
GitLab Admin area showing the Instance OAuth applications page with the Add new application button
If you do not have instance administrator access, you can instead create the application under User Settings → Applications, or under Group → Settings → Applications for a group you own. All three work. LowerPlane only needs the resulting Application ID and Secret.
2

Fill in the application form

Complete the Add new application form as shown below.
GitLab Add new application form with Name, Redirect URI, Trusted and Confidential checked, and read_api and read_user scopes selected
Name: enter a name your team will recognize, for example LowerPlane_App.Redirect URI: enter exactly:
https://api.lowerplane.com/api/v1/integrations/oauth/callback/gitlab_self_hosted
This value must match character for character, with no trailing slash. GitLab rejects the authorization request with “The redirect URI included is not valid” on any mismatch. This is the single most common cause of a failed self-managed setup.
Checkboxes:
OptionSettingWhy
TrustedEnabledTrusted applications are authorized automatically, so your users don’t see a consent screen on every connection.
ConfidentialEnabledLowerPlane authenticates with a client secret. Clearing this breaks the token exchange.
Device authorization grantDisabledNot used by LowerPlane. Leave it unchecked.
Scopes: select only these two:
  • read_api: grants read access to the API, including groups and projects
  • read_user: grants read-only access to the user profile
Leave every other scope unchecked.
3

Save and copy the credentials

Click Save application. GitLab confirms the application was created and shows the Application ID and Secret.
GitLab application detail page showing the Application ID and Secret fields, Callback URL, Trusted and Confidential set to Yes, and the read_api and read_user scopes
As GitLab notes on this page, this is the only time the secret is accessible. Copy both values somewhere secure before navigating away. Otherwise you’ll have to use Renew secret, which invalidates the old one.
Use this page to confirm the application is correct before continuing: Callback URL should match the Redirect URI above, Trusted and Confidential should both read Yes, and Scopes should list only read_api and read_user.

Step 2: Connect in LowerPlane

1

Open the integration

In LowerPlane, go to Settings > Integrations, find GitLab Self-Managed in the Version Control category, and click Connect.
2

Fill in the connection details

Three fields appear:
FieldWhat to enter
Hosted service URLYour instance domain without http:// or https://. If your instance is at https://gitlab.yourcompany.com, enter gitlab.yourcompany.com.
Application IDThe Application ID from Step 1.
Client SecretThe Secret from Step 1.
Pasting the full URL with a scheme or a trailing slash also works, since LowerPlane normalizes it to a bare host. The bare host is simply the canonical form.
3

Authorize on your instance

Click Connect with GitLab Self-Managed. You’ll be redirected to your own instance’s authorization page. Review the requested scopes and click Authorize.Sign in as the account that owns the groups you want covered. The connection inherits that account’s visibility, so LowerPlane can only see projects and groups that this account can see.
4

Initial sync

LowerPlane syncs your projects, members, and branch protection settings. This typically takes 1-2 minutes. Test results appear on the Tests page once the first sync completes.

Troubleshooting

The Redirect URI on your GitLab OAuth application does not match what LowerPlane sends. Open Admin Area → Applications, edit the application, and confirm the value is exactly:
https://api.lowerplane.com/api/v1/integrations/oauth/callback/gitlab_self_hosted
Check for a trailing slash, a missing /v1, http instead of https, or a copied leading space.
  • Re-check the Application ID and Client Secret for truncation or trailing whitespace.
  • Confirm the Confidential checkbox is enabled on the GitLab application. A non-confidential application will not accept the client secret.
  • Confirm the Hosted service URL points at the instance where you created the application.
  • Remove http:// or https:// and any trailing slash.
  • Confirm the host resolves publicly and serves a valid TLS certificate. Self-signed certificates are not accepted.
LowerPlane sees only what the authorizing account can see. Confirm that account is a member of the groups and projects you expect, then trigger a manual sync from Settings > Integrations > GitLab Self-Managed.
GitLab returns a group’s require_two_factor_authentication flag only to group Owners. Reconnect the integration using an account that is an Owner of that group, or mark the test as manually verified if owner access cannot be granted.
GitLab access tokens expire, and LowerPlane renews them automatically using the stored refresh token, so expiry alone will not break the integration.A connection that stops working usually means the OAuth application was deleted, its secret was regenerated with Renew secret, or the authorizing account lost access to the groups. Reconnect the integration to re-authorize.

Merge Request Reviews & Pipeline Status

LowerPlane collects approver names on merge requests and pipeline status results to verify that peer review and CI/CD gates are enforced before merging. This data is used by the “Code changes should be reviewed by peers” and “Merging should require passing status-checks” tests.

Data Access

Data TypeAccess
Project metadataRead
Branch protection rulesRead
Merge request reviews & approversRead
Pipeline status checksRead
Group membersRead
Group 2FA enforcement flagRead (requires the authorizing account to be a group Owner)
Source code / file contentsNo access
Commit history / diffsNo access
Issues / discussionsNo access