How to Connect GitLab to VERDiiiCT: Step-by-Step Guide
Overview
VERDiiiCT integrates with GitLab through an SCM connection (authenticated with a Personal Access Token) and a webhook (which triggers reviews automatically when merge requests are opened or updated). This works with both gitlab.com and self-hosted GitLab instances.
Note: GitLab uses the term Merge Request instead of Pull Request. VERDiiiCT handles this distinction automatically.
The process takes about five minutes:
- Create a Personal Access Token in GitLab
- Create an SCM connection in VERDiiiCT
- Register a webhook for your project
- Configure the webhook in GitLab
- Configure the webhook secret for payload verification
Prerequisites
- A VERDiiiCT account with Owner or Admin role in your organization
- A GitLab account with Maintainer or Owner role on the project you want to connect
- For self-hosted GitLab: the instance must be accessible from the internet
Step 1: Create a Personal Access Token in GitLab
VERDiiiCT uses a PAT to authenticate against the GitLab API — reading merge request diffs, fetching linked issues, and posting review comments.
- In GitLab, click your profile avatar in the top-left corner and select Edit profile
- In the left sidebar, click Access Tokens
- Click Add new token
- Configure the token:
- Token name:
VERDiiiCT Code Review - Expiration date: Choose an appropriate date (maximum 1 year on gitlab.com)
- Scopes: Select api (full API access — required for reading MR diffs, posting discussions, and setting commit statuses)
- Token name:
- Click Create personal access token and copy the token immediately — GitLab will not show it again
Security note: VERDiiiCT encrypts your PAT at rest using AES-256-GCM before saving it to the database. The plaintext token is never stored or logged.
Alternative for self-hosted: GitLab also supports Project Access Tokens and Group Access Tokens which are scoped to specific projects or groups. These are a good choice if you want to limit the token's access.
Step 2: Create an SCM Connection in VERDiiiCT
An SCM connection links your GitLab instance to VERDiiiCT.
- Log in to VERDiiiCT at app.verdiiict.com
- Navigate to Connections in the sidebar
- Click Add Connection
- Fill in the connection details:
- Provider: Select GitLab
- Display Name: A friendly name like
GitLab.comorCompany GitLab - Organization URL: Your GitLab instance URL — required
- For gitlab.com:
https://gitlab.com - For self-hosted:
https://gitlab.example.com
- For gitlab.com:
- Personal Access Token: Paste the PAT you created in Step 1
- Webhook Secret (optional): You can leave this blank — VERDiiiCT generates a unique secret per webhook registration automatically
- Click Create
- Use the Test Connection button to verify VERDiiiCT can authenticate with GitLab using your PAT
Step 3: Register a Webhook in VERDiiiCT
A webhook registration tells VERDiiiCT which project to watch and generates a unique callback URL along with a secret token.
- Open the connection you just created
- Navigate to the Webhooks tab
- Click Register Webhook
-
Fill in:
- Repository ID: The numeric GitLab project ID. You can find this on the project's main page under the project name, or via the API at
https://gitlab.com/api/v4/projects?search=your-project - Repository Name: The project name, e.g.
my-api - Events (optional): Defaults to
pull_request.createdandpull_request.updated. Leave as default.
- Repository ID: The numeric GitLab project ID. You can find this on the project's main page under the project name, or via the API at
-
Click Register
VERDiiiCT returns a Webhook URL and generates a Secret Token. The webhook URL follows this format:
https://api.verdiiict.com/api/webhooks/gitlab/{registration-id}
Important: Copy both the Webhook URL and the Secret Token. You will configure these in GitLab in the next step.
Step 4: Configure the Webhook in GitLab
- In your GitLab project, go to Settings → Webhooks
- Click Add new webhook
- Configure the webhook:
- URL: Paste the Webhook URL from VERDiiiCT
- Secret token: Paste the Secret Token from VERDiiiCT (the 64-character hex string)
- Under Trigger, check Merge request events and uncheck everything else
- Under SSL verification, leave Enable SSL verification checked (recommended)
- Click Add webhook
You can test the webhook by clicking Test next to "Merge request events" on the webhook detail page.
Step 5: How Secret Validation Works for GitLab
GitLab uses a simple token comparison for webhook secret validation — the simplest approach among all supported platforms.
The Validation Flow
When GitLab sends a webhook payload, it includes the secret token verbatim in the X-Gitlab-Token header:
X-Gitlab-Token: your-64-character-hex-secret-token
VERDiiiCT validates this by:
- Reading the
X-Gitlab-Tokenheader from the incoming request - Comparing it directly against the stored secret token
- Using constant-time comparison to prevent timing attacks
// Simplified validation logic
if (!headers.TryGetValue("X-Gitlab-Token", out var tokenHeader))
return false;
var receivedToken = tokenHeader.ToString();
// Constant-time comparison prevents timing attacks
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(secretToken),
Encoding.UTF8.GetBytes(receivedToken));How This Differs from Other Providers
| Provider | Validation Method | Header |
|----------|------------------|--------|
| GitHub | HMAC-SHA256 of body | X-Hub-Signature-256 |
| Gitea | HMAC-SHA256 of body | X-Gitea-Signature |
| Azure DevOps | Base64-encoded Basic Auth | Authorization |
| GitLab | Plain token comparison | X-Gitlab-Token |
GitLab doesn't use HMAC — the secret is sent as-is in the header. While this doesn't provide payload integrity verification (proving the body wasn't tampered with), it does authenticate that the request came from a source that knows the secret. VERDiiiCT uses constant-time comparison regardless to prevent timing side-channel attacks.
Security best practice: Always configure the webhook secret. Even though GitLab's approach is simpler than HMAC, it still prevents unauthorized parties from sending fake payloads to your webhook endpoint.
The Complete Flow
Once everything is configured, here's what happens automatically:
Developer opens or updates a Merge Request in GitLab
↓
GitLab fires the webhook (HTTP POST with X-Gitlab-Token header)
↓
VERDiiiCT receives the payload at /api/webhooks/gitlab/{id}
↓
VERDiiiCT validates the secret token (X-Gitlab-Token)
↓
VERDiiiCT filters for relevant actions:
- "open" → new MR, triggers review
- "update" → new commits pushed, triggers review
- Other actions (close, merge) → ignored
↓
VERDiiiCT fetches the MR diffs via GitLab API using the stored PAT
↓
AI (Claude or GPT) reviews the code changes
↓
VERDiiiCT posts inline discussion threads and a verdict
(Approved / Needs Work / Rejected) on the merge request
No manual steps required. Every merge request gets reviewed within minutes.
Troubleshooting
Webhook test returns an error
- Verify the webhook URL matches exactly what VERDiiiCT provided
- For self-hosted instances, ensure GitLab can reach the internet (some instances restrict outbound requests under Admin Area → Settings → Network → Outbound requests)
- Confirm the webhook registration is still active in VERDiiiCT
Webhook returns 401
- The secret token doesn't match. Copy the exact secret from VERDiiiCT and paste it into the GitLab webhook's Secret token field
- Make sure there are no trailing spaces or newlines in the token
Webhook returns 200 but no review appears
- VERDiiiCT only processes merge request events with action
openorupdate. Other actions (close, merge, approve) are accepted but ignored - Check that your PAT has the
apiscope - Verify the PAT hasn't expired
Reviews don't post inline comments
- Ensure the PAT has full
apiaccess (not justread_api) - For Project Access Tokens, verify the token role is at least Developer
- GitLab inline comments require SHA context (base, start, head commits) — if the MR has conflicts, comments may fail to position correctly
"Event ignored" response
VERDiiiCT only acts on merge_request events with action open (new MR) or update (new commits). GitLab sends many other actions (close, merge, approved, unapproved, etc.) that VERDiiiCT accepts but does not process.
GitLab-Specific Notes
gitlab.com vs Self-Hosted
Both work identically. The only difference is the Organization URL you provide:
| Instance | Organization URL |
|----------|-----------------|
| gitlab.com | https://gitlab.com |
| Self-hosted | https://gitlab.example.com |
VERDiiiCT appends /api/v4/ automatically when calling the GitLab API.
Merge Requests vs Pull Requests
GitLab uses the term Merge Request (MR) instead of Pull Request (PR). VERDiiiCT maps these internally:
- GitLab webhook event:
merge_request - GitLab MR identifier:
iid(project-scoped) — not the globalid - VERDiiiCT treats MRs identically to PRs from other providers
Auth Header
GitLab uses a custom PRIVATE-TOKEN header instead of Authorization: Bearer:
PRIVATE-TOKEN: your-personal-access-token
VERDiiiCT handles this automatically — you just provide the token when creating the connection.
Inline Comments Require SHA Context
Unlike GitHub (where you just post line numbers), GitLab requires base_sha, start_sha, and head_sha to position inline discussion threads. VERDiiiCT fetches these from the MR diff versions endpoint automatically.
What's Next
- How to Connect GitHub to VERDiiiCT — if you also use GitHub
- How to Connect Azure DevOps to VERDiiiCT — if you also use Azure DevOps
- How to Connect Gitea to VERDiiiCT — if you also use Gitea
- How to Connect Bitbucket to VERDiiiCT — if you also use Bitbucket