> ## Documentation Index
> Fetch the complete documentation index at: https://docs.backline.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# GitLab Self-Managed Integration

> Connect your self-hosted GitLab instance to Backline

## Overview

Backline integrates with GitLab Self-Managed (self-hosted) to automatically create merge requests that remediate known vulnerabilities in your repositories.

Backline supports two connection modes for GitLab Self-Managed:

* **Direct connection** — Backline connects to your GitLab instance directly. This is the simplest setup and requires no additional infrastructure. Use this mode if Backline has access to your GitLab instance.

* **On-Premise agent** — A lightweight Backline agent runs inside your network and handles all communication using outbound-only connections. No inbound connections are required.
  You choose the connection mode when setting up the integration. It can be changed later by disconnecting and reconnecting.

<Note>
  Looking for GitLab.com (cloud)? See the [GitLab integration](/integrations/gitlab) instead.
</Note>

## What You Can Do

With the GitLab Self-Managed integration, Backline can:

* Access your GitLab projects and groups
* Analyze dependencies and detect outdated packages
* Create merge requests with security patches
* Track remediation progress across your GitLab projects

## Prerequisites

Before connecting GitLab Self-Managed, ensure you have:

* A GitLab Self-Managed instance
* A token with Developer role on the projects you want Backline to manage: a service account, a group access token, or a personal access token (PAT). Backline onboards every project the token is a member of.
* An access token with the required scopes

**Additional prerequisites for on-premise agent mode:**

* The Backline Helm chart already installed in your Kubernetes cluster

## Network Requirements

### Direct Connection Mode

Your GitLab instance must be reachable from Backline's cloud infrastructure. Allowlist Backline's IP ranges if your instance is behind a firewall — contact [support@backline.ai](mailto:support@backline.ai) for the current IP list.

| Direction                    | Destination         | Port      | Protocol   | Purpose            |
| ---------------------------- | ------------------- | --------- | ---------- | ------------------ |
| **Inbound** (to your GitLab) | From Backline cloud | 443 or 80 | HTTPS/HTTP | Git API operations |

### On-Premise Agent Mode

The Backline on-premise agent requires the following network access:

| Direction    | Destination                     | Port      | Protocol   | Purpose                           |
| ------------ | ------------------------------- | --------- | ---------- | --------------------------------- |
| **Outbound** | `app.backline.ai`               | 443       | HTTPS      | Communication with Backline cloud |
| **Outbound** | Your GitLab Self-Managed server | 443 or 80 | HTTPS/HTTP | Git API operations                |
| **Inbound**  | None                            | —         | —          | No inbound connections required   |

<Note>
  The agent connects to your GitLab server **directly** (not through Backline cloud). If your cluster routes outbound traffic through a corporate proxy, set the proxy in your Backline values and list your GitLab host (or internal domain) under `proxy.noProxy` so the agent reaches it directly — otherwise the connection fails with `Bad Gateway`. See [Routing through a corporate proxy](#routing-through-a-corporate-proxy) below.
</Note>

<Note>
  If your GitLab server uses a TLS certificate signed by an **internal or corporate CA**, the agent must be given that CA to trust it — otherwise the connection fails with `x509: certificate signed by unknown authority`. See [Trusting an Internal CA](#trusting-an-internal-ca) below.
</Note>

## Creating an Access Token

Backline needs a token with access to the projects you want to manage. Backline onboards every project the token is a member of.

### Supported Token Types

GitLab supports several token types that Backline can use:

* **Service Account Token** — available on GitLab Premium/Ultimate. A machine user not tied to a person, suited for automation. Requires Developer role on the projects.
* **Group Access Token** — A token scoped to a group (and its subgroups). GitLab automatically creates a dedicated user for it. Requires Developer role.
* **Personal Access Token (PAT)** — tied to a specific user account. The user must have Developer role on the projects.

<Tip>
  We recommend using a **Service Account Token** or **Group Access Token** so the integration is not tied to any individual's account.
</Tip>

### Required Scopes

Configure your token with the following scopes:

* `api` - Full API access for managing projects, merge requests, and webhooks
* `read_repository` - Clone and read repository content
* `write_repository` - Create branches, commit changes, and push code

<Warning>
  The token's permissions in GitLab determine which repositories are included. Ensure it covers all projects you want to remediate.
</Warning>

### Setting Up the Account

<Steps>
  <Step title="Create a dedicated account">
    In your GitLab instance, create one of the following with **Developer role on the projects you want to manage**: a **service account**, a **group access token**, or a **personal access token (PAT)**.
  </Step>

  <Step title="Generate an access token">
    Generate an access token for that account with the `api`, `read_repository`, and `write_repository` scopes. Set an appropriate expiration date for your security policy.
  </Step>

  <Step title="Copy the token value">
    Copy the generated token value. You won't be able to see it again after leaving the page.
  </Step>
</Steps>

## Enabling On-Premise Git Support

<Note>
  This section only applies if you chose the **on-premise agent** connection mode. If Backline has direct access to your GitLab instance and you're using **direct connection**, skip to [Connecting GitLab Self-Managed](#connecting-gitlab-self-managed).
</Note>

The on-premise agent mode requires an additional component in your Backline deployment that handles communication with your git server. Enable it by upgrading your existing Backline release:

```bash theme={null}
helm upgrade backline backline/backline \
  --namespace backline \
  --reuse-values \
  --set gitproxy.enabled=true
```

Verify the pod is running:

```bash theme={null}
kubectl get pods -n backline -l app=gitproxy
```

You should see output similar to:

```
NAME                        READY   STATUS    RESTARTS   AGE
gitproxy-6d4f8b7c9-x2k5n   1/1     Running   0          30s
```

## Routing through a corporate proxy

If your cluster reaches the internet through a corporate HTTP(S) proxy, set it in your Backline values so the worker, gitproxy and janitor use it. List your **internal** GitLab host (or domain) and in-cluster addresses under `noProxy` so the agent reaches them **directly** — otherwise requests to your internal server are sent to the egress proxy and fail with `Bad Gateway`.

```bash theme={null}
helm upgrade backline backline/backline \
  --namespace backline \
  --reuse-values \
  --set gitproxy.enabled=true \
  --set proxy.httpProxy=http://proxy.company.com:3128 \
  --set proxy.httpsProxy=http://proxy.company.com:3128 \
  --set proxy.noProxy="gitlab.company.com,.company.com,.svc,.cluster.local,10.0.0.0/8"
```

The settings are applied to the worker, gitproxy and janitor components. Leave them unset to connect directly.

## Trusting an Internal CA

If your GitLab server's TLS certificate is signed by an **internal or corporate CA** (not a public one), the agent must be given that CA — otherwise connections fail with `x509: certificate signed by unknown authority`. A CA *certificate* is public (not a secret), so it's safe to provide.

<Steps>
  <Step title="Base64-encode your CA certificate">
    Encode the CA certificate (PEM) that signs your GitLab server's certificate into a single line:

    ```bash theme={null}
    base64 -w0 ca.pem > ca.b64                 # Linux
    # macOS / portable:
    base64 < ca.pem | tr -d '\n' > ca.b64
    ```
  </Step>

  <Step title="Provide it to the agent">
    Upgrade your Backline release with the encoded CA via `customCaCert`:

    ```bash theme={null}
    helm repo update
    helm upgrade backline backline/backline \
      --namespace backline \
      --reuse-values \
      --set gitproxy.enabled=true \
      --set-file customCaCert=ca.b64
    ```

    You can also place the base64 string under `customCaCert` in your values file instead of using `--set-file`.
  </Step>

  <Step title="Verify and retry">
    Confirm the agent pod is Running, then retry **Test Connection**:

    ```bash theme={null}
    kubectl get pods -n backline -l app=gitproxy
    ```
  </Step>
</Steps>

## Connecting GitLab Self-Managed

<Steps>
  <Step title="Navigate to Integrations">
    In Backline, go to the Integration Hub from the main menu.
  </Step>

  <Step title="Select GitLab Self-Managed">
    Find and click **Connect** on the **GitLab Self-Managed** integration card.
  </Step>

  <Step title="Enter Connection Details">
    Fill in the connection form:

    * **GitLab Instance URL** — The base URL of your GitLab Self-Managed instance (e.g., `https://gitlab.company.com`). This is your server's root URL, not a project or group URL.
    * **Access Token** — The token created in the previous step
    * **Route via Proxy** — Enable this if connecting to your GitLab instance should route through the Backline proxy agent (on-premise agent mode). Disable it if Backline has direct access to your GitLab instance.
  </Step>

  <Step title="Connect">
    Click **Connect**. Backline will automatically test the connection to your GitLab instance before saving the integration. During this step, Backline validates the token and onboards all projects it is a member of. If the test fails, you'll see an error with details about what went wrong.
  </Step>
</Steps>

## After Connection

Once GitLab Self-Managed is connected, Backline will:

1. Discover and catalog every project the token is a member of
2. Generate remediation plans for vulnerabilities from those repositories
3. Create merge requests for approved fixes

## Managing the Integration

### Testing Connections

To verify that a connection is still valid:

1. Open the integration details by clicking **Configure** on the GitLab Self-Managed integration card
2. Click the **three dots menu** on the connection
3. Select **Test Connection** to validate connectivity and credentials

### Updating Access

To rotate your token or update credentials:

1. Generate a new token in your GitLab instance
2. Return to the GitLab Self-Managed integration card in Backline
3. Click **Configure** and update the token field

### Upgrading the On-Premise Agent

```bash theme={null}
helm repo update
helm upgrade backline backline/backline \
  --namespace backline \
  --reuse-values
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="On-Premise git pod is in CrashLoopBackOff">
    * Verify `gitproxy.enabled` is set and the `accessKey` is configured:
      ```bash theme={null}
      helm get values backline -n backline
      ```
    * View the pod logs for specific error messages:
      ```bash theme={null}
      kubectl logs -n backline -l app=gitproxy --previous
      ```
  </Accordion>

  <Accordion title="Test Connection fails">
    * Verify the on-premise agent is running: `kubectl get pods -n backline -l app=gitproxy`
    * Test outbound connectivity to Backline cloud from the agent:
      ```bash theme={null}
      kubectl exec -n backline deploy/gitproxy -- \
        wget -q --spider https://app.backline.ai/health
      ```
    * Confirm the **GitLab Instance URL** is correct and reachable from the agent's network
    * Check that the **Access Token** is valid and has not expired
    * Ensure the token has the required scopes: `api`, `read_repository`, `write_repository`
    * Ensure the token is a member of at least one project with Developer role
  </Accordion>

  <Accordion title="Test Connection fails with a Bad Gateway error">
    `Bad Gateway` means the agent's request to your GitLab server is being routed through your cluster's outbound proxy, which can't reach an internal server.

    Your GitLab server should be reached **directly**. Add its host (or your internal domain) to `proxy.noProxy` in your Backline values and upgrade — see [Routing through a corporate proxy](#routing-through-a-corporate-proxy). The agent rolls out automatically with the new setting.
  </Accordion>

  <Accordion title="Test Connection fails with a certificate error">
    `x509: certificate signed by unknown authority` means your GitLab server's TLS certificate is signed by an internal/corporate CA that the agent doesn't trust (it ships only standard public CAs).

    Provide your CA to the agent following [Trusting an Internal CA](#trusting-an-internal-ca), then retry **Test Connection**.
  </Accordion>

  <Accordion title="No projects found during connection">
    Backline validates the token and onboards every project it is a member of. If none is found, the connection will fail.

    * Verify the token is a member of at least one project with Developer role
    * For Group Access Tokens, ensure the token is created at the group level (not project level)
    * For Personal Access Tokens, ensure the user is a member of at least one project with Developer role
  </Accordion>

  <Accordion title="Merge requests are not being created">
    * Verify the account has write access to the repositories in the group
    * Ensure the token has `write_repository` scope
    * Review the on-premise agent logs: `kubectl logs -n backline -l app=gitproxy --tail=200`
  </Accordion>

  <Accordion title="Connection was working but stopped">
    * Check that the on-premise agent is still running
    * Verify the access token has not expired
    * Confirm no network changes have blocked outbound connectivity to `app.backline.ai`
  </Accordion>
</AccordionGroup>

For additional help, contact [support@backline.ai](mailto:support@backline.ai).
