Production guide for running CodeGraph against self-managed GitLab Community Edition in a local contour with internal DNS, private CA, local runners, and no mandatory internet egress.
Table of Contents¶
- Overview
- Local Contour Profile
- Provider Connection and Trust
- Config-Backed Import through Repositories Center
- Webhook Setup and Recovery
- CI Template for Local Runners
- REST, CLI, and MCP Surfaces
- Rotation Workflows
- Troubleshooting
- Production Readiness
Overview¶
CodeGraph supports GitLab CE through the canonical provider-connection and repository-binding model. The production-ready path for a local contour now covers:
- host-aware provider connections for self-managed GitLab CE;
- custom CA bundle metadata and authenticated health checks;
- webhook ingestion for push and merge request events with delivery diagnostics;
- reconcile and replay workflows for missed events and degraded sync;
- merge request review snapshots with native publication back to GitLab notes;
- operator-visible status for webhook freshness, repository head, CPG head, and review publication;
- a local-runner
.gitlab-ci.ymltemplate that writes JSON, Markdown, and SARIF artifacts without depending on GHCR at runtime.
This guide is intentionally GitLab CE-first. It does not assume GitLab.com, GitLab EE-only features, or public registry access.
Local Contour Profile¶
Recommended deployment topology:
- GitLab CE is exposed on an internal hostname such as
gitlab.internal. - CodeGraph API is exposed on an internal hostname such as
codegraph.internal. - A reverse proxy forwards
POST /api/v1/admin/runtime/webhooks/gitlabto CodeGraph without rewriting the body or droppingX-Gitlab-*headers. - GitLab runners pull a preloaded CodeGraph image from an internal container registry such as
registry.internal/platform/codegraph-runner:stable. - CodeGraph containers trust the same private CA bundle that signs the GitLab CE and reverse-proxy certificates.
Reverse proxy requirements:
- preserve
X-Forwarded-Proto,Host, andX-Gitlab-*headers; - allow request bodies large enough for merge request payloads;
- do not buffer or rewrite webhook JSON;
- permit fast
202 Acceptedresponses while background work continues asynchronously.
Minimum machine credential expectation:
- use a service account or PAT, not a human browser session;
- for read-only provider diagnostics and MR fetch,
read_apiis acceptable where available; - for native merge-request comment publication, use a token with
apiscope.
Provider Connection and Trust¶
Create a GitLab CE provider connection with explicit host, API version, and CA bundle metadata:
codegraph repos connect-provider `
--group default `
--name gitlab-ce-local `
--provider gitlab `
--host gitlab.internal `
--base-url https://gitlab.internal `
--api-version v4 `
--ca-bundle-path C:\certs\gitlab-root-ca.pem `
--token $env:GITLAB_TOKEN `
--webhook-secret $env:GITLAB_WEBHOOK_SECRET
What this persists:
provider_hostbase_urlmetadata.api_versionmetadata.ca_bundle_path- service credential and webhook secret
Run the operator health check immediately after connection creation:
codegraph repos provider-health --group default --connection gitlab-ce-local
The health check verifies:
- hostname reachability;
- TLS trust using the configured CA bundle;
- GitLab API v4
versionendpoint reachability; - authenticated
/useraccess when a token is configured.
Typical degraded classifications are surfaced as operator-facing categories and reasons:
dns_error:host_resolution_failedtls_error:tls_verification_failedauth_error:auth_rejectedprovider_http_error:endpoint_not_foundversion_mismatchprovider_outage
Repository onboarding remains stable across namespace/path rename as long as the external repository ID stays constant:
codegraph repos import `
--group default `
--connection gitlab-ce-local `
--repo platform/api `
--sync-mode webhook
Config-Backed Import through Repositories Center¶
In corporate deployments, declare one or more GitLab CE installations in config.yaml so they appear automatically on http://127.0.0.1:3100/dashboard/repositories.
Minimal example without committing secrets to config:
repository_providers:
sync_configured_connections_on_startup: true
gitlab_ce:
- name: gitlab-ce-local
group: default
provider_host: gitlab.internal
base_url: https://gitlab.internal
api_version: v4
token_env: GITLAB_TOKEN
webhook_secret_env: GITLAB_WEBHOOK_SECRET
ca_bundle_path: C:\certs\gitlab-root-ca.pem
request_timeout_seconds: 15
default_sync_mode: webhook
is_active: true
Set the runtime environment variables before starting CodeGraph:
$env:GITLAB_TOKEN="glpat-..."
$env:GITLAB_WEBHOOK_SECRET="..."
python scripts/run_app_stack.py restart --local --with-mcp
UI process:
- Open
http://127.0.0.1:3100/dashboard/repositories. - Switch to
Discovered repositories. - Select the connection marked
from config. - Click
Check connectionand confirm the health check is healthy or returns an actionable degraded reason. - Enter the namespace/group, for example
platform, and run discovery. - Import the target repository. Use
webhooksync mode by default for this installation. - Configure the GitLab project webhook to
POST /api/v1/admin/runtime/webhooks/gitlabwith the secret fromGITLAB_WEBHOOK_SECRET. - After the first push, or manually with
codegraph repos reconcile --group default --project <project>, verify thatrepository_head_shaequalscpg_head_shaandfreshness_reason=commit_match.
Config sync only creates or updates managed ProviderConnection records. It never deletes manually created connections that are absent from config.yaml.
Webhook Setup and Recovery¶
Webhook endpoint:
POST /api/v1/admin/runtime/webhooks/gitlab
GitLab project setup:
- Open
Settings > Webhooks. - Configure
https://codegraph.internal/api/v1/admin/runtime/webhooks/gitlab. - Set the same secret token used in the provider connection.
- Enable
Push eventsandMerge request events. - Keep SSL verification enabled. Do not disable TLS verification to work around a missing CA bundle.
Webhook behavior:
- CodeGraph returns
202 Acceptedquickly and enqueues durable sync/review work asynchronously. - Missing GitLab webhook secret returns
401 Unauthorized; invalid secret returns403 Forbidden. - Push events are deduplicated by binding and event identity.
- Merge request events participate in review-snapshot lifecycle and deduplication.
- Delivery diagnostics are stored on the repository binding and surfaced back to operators.
Operational recovery flow:
codegraph repos status --group default --project api
codegraph repos reconcile --group default --project api
codegraph repos jobs --group default --project api --status failed
codegraph repos replay --job-id <failed-sync-job-uuid>
codegraph repos review-snapshots --group default --project api --status failed
GET /api/v1/admin/runtime/webhooks/status/{project_id} now returns both legacy update-pipeline state and GitLab binding diagnostics. project_id may be a project name or a project UUID.
Example response:
{
"project_id": "api",
"last_update": "2026-04-19T12:05:00+00:00",
"status": "completed",
"commit_sha": "9f21f4e",
"duration_ms": 2310,
"gocpg_status": "completed",
"openviking_synced": 3,
"last_webhook_received_at": "2026-04-19T12:03:10+00:00",
"last_webhook_delivery_at": "2026-04-19T12:03:10+00:00",
"last_webhook_delivery_status": "accepted",
"last_webhook_delivery_reason": "event_accepted",
"last_webhook_delivery_event_type": "merge_request",
"last_webhook_delivery_id": "2ea7b29d-d418-4cf9-86d6-1d86f32a4488",
"last_reconcile_at": "2026-04-19T11:48:02+00:00",
"webhook_health_status": "healthy",
"reconcile_health_status": "healthy",
"repository_head_sha": "9f21f4e",
"cpg_head_sha": "9f21f4e",
"last_review_publish_at": "2026-04-19T12:04:13+00:00",
"last_review_publish_status": "published",
"last_review_publish_reason": "published",
"last_review_publish_category": "ok",
"last_review_publish_error": null,
"error": null
}
CI Template for Local Runners¶
Reference template:
docs/integrations/examples/gitlab_ce_local_contour.gitlab-ci.yml
What the template assumes:
CODEGRAPH_RUNNER_IMAGEpoints to an internal registry image already mirrored into the local contour;CODEGRAPH_TOKENis a masked GitLab CI variable;INTERNAL_CA_BUNDLE_PATHpoints to the CA bundle mounted into the runner image or shell executor;- merge request and default-branch pipelines have access to full git history with
GIT_DEPTH: "0".
The template produces:
codegraph-artifacts/security/findings.jsoncodegraph-artifacts/security/findings.sarifcodegraph-artifacts/review/review-summary.jsoncodegraph-artifacts/review/review-summary.mdcodegraph-artifacts/artifact-index.json
These artifacts give a stable production contour for:
- machine-readable JSON findings;
- SARIF export for downstream security tooling;
- Markdown review summaries that can be attached to MR discussions or retained as operator evidence.
Required GitLab CI/CD variables:
| Variable | Purpose |
|---|---|
CODEGRAPH_TOKEN |
Bearer token used to call the CodeGraph API |
CODEGRAPH_API_URL |
Internal CodeGraph API origin, for example https://codegraph.internal |
CODEGRAPH_RUNNER_IMAGE |
Internal registry image used by local runners |
INTERNAL_CA_BUNDLE_PATH |
Mounted path to the private CA bundle inside the runner environment |
REST, CLI, and MCP Surfaces¶
REST surfaces:
POST /api/v1/admin/runtime/webhooks/gitlabGET /api/v1/admin/runtime/webhooks/status/{project_id}POST /api/v1/review/mrPOST /api/v1/security/scan-diffGET /api/v1/repositories/bindingsPOST /api/v1/repositories/provider-connections/{connection_id}/health-check
CLI surfaces:
codegraph repos provider-health --group default --connection gitlab-ce-local
codegraph repos status --group default --project api
codegraph repos reconcile --group default --project api
codegraph repos replay --job-id <sync-job-uuid>
codegraph repos review-rerun --snapshot-id <snapshot-uuid> --publish-review
MCP surfaces that remain relevant for GitLab-bound repositories:
codegraph_repository_reconciliation_runcodegraph_repository_statuscodegraph_repository_sync_jobscodegraph_review_snapshotscodegraph_review_snapshot_rerun
Rotation Workflows¶
Rotate a GitLab service credential without re-importing the bound repository:
codegraph repos rotate-provider-token `
--group default `
--connection gitlab-ce-local `
--token $env:GITLAB_TOKEN_V2 `
--webhook-secret $env:GITLAB_WEBHOOK_SECRET_V2
Rotate the CA bundle path or API metadata in place:
codegraph repos update-provider `
--group default `
--connection gitlab-ce-local `
--ca-bundle-path C:\certs\gitlab-root-ca-v2.pem `
--api-version v4
Recommended post-rotation flow:
- Rotate token or webhook secret.
- Run
codegraph repos provider-health. - Check
codegraph repos statusfor webhook and publication diagnostics. - Trigger
codegraph repos reconcileif repository freshness is behind the provider head.
Human OAuth remains optional for machine workflows. Self-managed GitLab OAuth custom server URL support already exists, but webhook, sync, reconcile, and MR publication do not require a browser login.
Troubleshooting¶
auth_error:auth_rejected¶
- verify the PAT/service token is still valid;
- verify the token has the scope needed for the current workflow;
- rotate the token with
codegraph repos rotate-provider-token, then reruncodegraph repos provider-health.
tls_error:tls_verification_failed¶
- verify the CA bundle path stored on the provider connection;
- ensure the runner and CodeGraph containers mount the same updated CA bundle;
- do not switch to insecure TLS as a workaround.
dns_error:host_resolution_failed¶
- verify the GitLab CE hostname resolves from the CodeGraph runtime and from local runners;
- check internal DNS and reverse-proxy upstream mapping.
last_webhook_delivery_status=deduplicated¶
- this is normally healthy and indicates an already-seen delivery identity or review snapshot key;
- only investigate if the repository head and CPG head diverge afterward.
last_review_publish_status=failed¶
- inspect
last_review_publish_reason,last_review_publish_category, andlast_review_publish_error; - if credentials were rotated recently, rerun provider health;
- rerun the failed review snapshot with
codegraph repos review-rerun --publish-review.
Repository head is ahead of CPG head¶
- run
codegraph repos status --project <project>; - if webhook delivery is stale or skipped, run
codegraph repos reconcile --project <project>; - inspect failed sync jobs and replay them if the root cause is already fixed.
Production Readiness¶
The GitLab CE integration guide describes the public runtime, webhook, CI, SAST, health, and troubleshooting surfaces. Internal rollout and acceptance artifacts are not part of the public documentation set.