GitLab
Broker GitLab.com or a self-managed instance: Git, merge requests, pipelines, and job traces through the same broker paths and the same agentgate pr and agentgate ci commands. No Git LFS yet.
Enable with AGENTGATE_PROVIDER=gitlab and "provider": "gitlab" in the config; the daemon refuses to start if the two disagree. examples/config.gitlab.json is a starting point. One provider per broker.
Credential model
- Root credential: an OAuth 2.0 refresh token for a confidential GitLab application (scope
apifor merge requests and pipelines, orread_apipluswrite_repositoryfor Git only), held in an owner-only file named byAGENTGATE_GITLAB_REFRESH_TOKEN_FILE, with the client id inAGENTGATE_GITLAB_CLIENT_IDand the client secret inAGENTGATE_GITLAB_CLIENT_SECRET_FILE. The workspace never mounts any of them. - Short-lived credential: the broker exchanges the refresh token at
<base>/oauth/tokenfor a two-hour access token, cached until 60 seconds before expiry and re-exchanged after that or after any upstream 401. Concurrent first requests share one exchange, because a refresh token is single use. - Rotation: GitLab returns a new refresh token on every exchange and invalidates the old one. The adapter writes it to the file atomically (mode 0600, rename) before using the access token, so a restart never presents a spent token. The file must be writable by the broker (Compose: a named volume, not a read-only secret).
- Where the token goes: only the origin in
AGENTGATE_GITLAB_URL(defaulthttps://gitlab.com, https only, fixed at startup). Git requests carry it asBasic oauth2:<token>, API requests asBearer <token>.
Broader than a GitHub App token
An OAuth token carries the user's full scope on every project the user can reach and cannot be narrowed per request. The broker's default-deny policy is the boundary, and the OAuth user should be a dedicated bot account with Developer role only on the configured projects. Treat the bot user's project membership as part of the policy. Rotate by revoking the application, not by deleting the file.
Configuration
| Field | Required | Notes |
|---|---|---|
provider | yes | "gitlab", must equal AGENTGATE_PROVIDER |
repositories[].name | yes | group/project, nested groups allowed; no .git; lowercased |
repositories[].projectId | yes | Numeric project id; used by API calls and as the duplicate and mirror key |
protectedBranches, allowedPushOptions, allowUnicodeRefs, forkOf, scan | no | As for GitHub |
id, installationId, and allowWorkflowWrites are GitHub-only and refused.
Policy actions
| Action | Approval |
|---|---|
git.read, git.push | As for GitHub |
gitlab.mr.read | allow/deny |
gitlab.mr.create | allow/deny/approval, head ref pattern; fork MRs are created on the fork project |
gitlab.mr.comment | allow/deny; a review is a note, since GitLab has no comment-only review object |
gitlab.mr.merge | approval or deny only, with sha and squash; mergeMethods accepts merge and squash (rebase is a project setting and is refused) |
gitlab.pipelines.read | allow/deny: pipelines, jobs, and job traces |
Approvals stay human-only exactly as for GitHub. Job traces return in the response body; a redirect is reported as a failure and never followed. Protected branches are verified at startup and hourly, as for GitHub.
Workspace
The broker serves the same paths as for GitHub (/<group>/<project>.git/... and /api/repos/<group>/<project>/...), so the workspace CLI is unchanged. Set AGENTGATE_PROVIDER_HOST in the workspace so URL rewriting and agentgate pr recognise the host, and add the GitLab host to the egress proxy deny list so the workspace can reach it only through the broker (GitHub is denied by default; GitLab is deployment specific).
Responses are projected to the GitHub-shaped fields the CLI prints (merge request as number, title, state, draft, head, base; pipelines as workflow_runs; jobs with steps: []). No field carries a credential; author emails, project objects, and pipeline variables are never projected.
Deferred
- Git LFS via GitLab (
providerCapabilitiesreportslfs: false; the LFS batch route answers 404). - An automated live smoke test; the manual procedure is in
docs/providers/gitlab.md. - Per-project access-token credential mode.