---
title: GitLab SCM
description: Merge requests, discussions, and pipelines via the glab CLI.
---

<div style={{ display: "flex", alignItems: "center", gap: "0.75rem", margin: "0.5rem 0 1.25rem" }}>
  <Logo name="gitlab" size={28} color />
  <span style={{ fontSize: "0.8125rem", color: "var(--color-fd-muted-foreground)" }}>Slot: <code>scm</code> · Name: <code>gitlab</code></span>
</div>

<PlatformSupport macos="full" linux="full" windows="full" />

## Setup

```bash
glab auth login
```

```yaml title="agent-orchestrator.yaml"
scm: gitlab
scmConfig:
  host: gitlab.com       # default; override for self-hosted
```

## Mapping

| Concept | GitHub term | GitLab term |
|---|---|---|
| Review request | Pull request | Merge request |
| Review | Review | Discussion / note |
| CI status | Check runs | Pipelines / jobs |

AO normalises these internally — the dashboard and lifecycle state machine don't know which you use.

## Webhook endpoint

AO's dashboard receives webhook events at:

```
POST /api/webhooks
```

The absolute URL is `https://<your-ao-host>/api/webhooks`. To expose your local dashboard publicly, see [Remote access](/docs/configuration/remote-access).

### GitLab project settings

In your GitLab project go to **Settings → Webhooks → Add new webhook**:

- **URL**: `https://<your-ao-host>/api/webhooks`
- **Secret token**: the value of your `secretEnvVar` environment variable
- **Trigger events**: Merge request events, Pipeline events, Push events, Note events (review comments)

### Config

```yaml
scm: gitlab
projects:
  myproject:
    repo: group/project
    scm:
      webhook:
        secretEnvVar: GITLAB_WEBHOOK_TOKEN    # env var holding the token
```

Full `webhook.*` sub-object:

| Field | Default | Description |
|---|---|---|
| `enabled` | `true` | Enable or disable webhook processing |
| `path` | `/api/webhooks` | Override the receive path |
| `secretEnvVar` | — | Name of the env var holding the token |
| `signatureHeader` | `x-gitlab-token` | Header carrying the secret token |
| `eventHeader` | `x-gitlab-event` | Header carrying the event type |
| `deliveryHeader` | `x-gitlab-event-uuid` | Header carrying the delivery UUID |
| `maxBodyBytes` | unlimited | Reject payloads larger than this (bytes) |

**Verification**: GitLab sends the configured secret as a literal string in `X-Gitlab-Token`. AO compares this value directly (no HMAC — unlike GitHub's SHA-256 approach).

Polling is still active as a fallback — webhooks are a latency optimisation, not a hard dependency.

## Automated review authors

AO ignores review comments from known bot accounts so they don't block the merge-readiness check. The full list:

**Hardcoded bots:**

| Username |
|---|
| `gitlab-bot` |
| `ghost` |
| `dependabot[bot]` |
| `renovate[bot]` |
| `sast-bot` |
| `codeclimate[bot]` |
| `sonarcloud[bot]` |
| `snyk-bot` |

**Runtime catch-all:** any username matching `/^project_\d+_bot/` (GitLab project access tokens) or ending in `[bot]`.

See [Review loop — bot detection](/docs/guides/review-loop#automated-review-bugbot-detection) for how AO uses this list during the review-pending → mergeable transition.
