Skip to content

GitLab Source

What it ingests

Project activity — merge requests, issues, commits, and the comments (notes/discussions) on merge requests and issues — across a single group (including its subgroups) or an explicit list of projects.

Works against GitLab.com by default and against a self-hosted instance when you set base_url.

Credential

The GitLab source references a gitlab_token credential by id. Any of GitLab's three access-token flavors works — they are identical on the wire:

TokenWhere to create itUse it when
Personal access tokenUser → Preferences → Access tokensYou want one credential across several groups
Group access tokenGroup → Settings → Access tokensYou are ingesting one group (least privilege)
Project access tokenProject → Settings → Access tokensYou are ingesting a fixed project list

Required scope: read_api. (api also works but grants writes the source never makes.) For a group or project token, the Reporter role is enough.

bash
curl -sS -X POST https://your-corveil-host/api/credentials \
  -H "Authorization: Bearer <admin>" -H "Content-Type: application/json" \
  -d '{"type":"gitlab_token","name":"acme-gitlab-ro","secret":"glpat-..."}'

Copy the returned credential id.

One token, one instance

A token is scoped to the instance that issued it. A gitlab.com token will not authenticate against gitlab.acme.com, so a self-hosted source needs its own credential alongside its own base_url.

Config fields

KeyRequiredNotes
groupone of group / projectsFull group path, including parents — acme or acme/platform. Subgroups are included.
projectsone of group / projectsComma-separated full project paths, e.g. acme/api, acme/platform/web.
base_urlnoSelf-hosted instance URL. Defaults to https://gitlab.com.

Provide either a group or an explicit project list (or both — they are unioned, not one overriding the other).

Notes on the values:

  • Paths are the full path as it appears in the URL. For https://gitlab.com/acme/platform/web, the project is acme/platform/web, not web.
  • base_url must be https (plain http is accepted only for localhost, for development). Include a subpath if your instance is mounted on one, e.g. https://example.com/gitlab.
  • An invalid path or a plaintext-http base_url is rejected when you save the source, not silently on every later poll.

Provider-side setup

  1. Create the access token above with the read_api scope.
  2. Give it access to the group or projects you want to ingest — for a personal token that means the account is a member; for a group/project token the role is granted at creation.
  3. For a self-hosted instance, make sure the Corveil deployment can reach it over HTTPS.

Wire-up

POST /api/sensors

json
{
  "sensor_type": "gitlab",
  "name": "Acme GitLab",
  "config": { "group": "acme" },
  "credentials": { "token": "<gitlab_token credential id>" }
}

Scoped to specific projects instead:

json
{
  "sensor_type": "gitlab",
  "name": "Acme API + Web",
  "config": { "projects": "acme/api, acme/platform/web" },
  "credentials": { "token": "<gitlab_token credential id>" }
}

Self-hosted:

json
{
  "sensor_type": "gitlab",
  "name": "Acme Internal GitLab",
  "config": { "group": "platform", "base_url": "https://gitlab.acme.com" },
  "credentials": { "token": "<gitlab_token credential id>" }
}

What lands in the ontology

The source stamps a signal on every event; the default bindings map each one to an entity type. You can preview and edit these on the Add sensor form and change them later in the source's bindings drawer.

SignalEntityNotes
pushRepository, OrganizationThe project, and the top-level group as the Organization
merge_requestPullRequestNamed group/project!12 — the same type GitHub PRs use, so cross-provider queries work
issueIssueNamed group/project#7
commitCommitFrom the backfill
noteCommentComments on merge requests and issues

People are resolved from the actor on each event and deduplicated against identities from your other sources.

Merge requests and issues can share a number

GitLab numbers them in separate sequences, so !12 and #12 are different objects. The sigils are part of the entity name for exactly that reason.

Verify

Use Test connection on the source — it authenticates against GET /api/v4/user on the configured instance. Then watch the first poll: a healthy source reports events flowing.

Common failures and what they mean:

  • 401 — the token is wrong, revoked, or belongs to a different instance.
  • 403 — the token is valid but its scope is too narrow; it needs read_api.
  • 404 on a group or project you know exists — GitLab answers 404 rather than 403 for something a token cannot see, so this is usually a membership or scope gap rather than a typo. The source's error message says so.