gitlabDefault host:
gitlab.com (configurable for self-managed instances)
Quick start
Authenticate with the GitLab CLI or export a Personal Access Token:Credential discovery
Cynative resolves a token for the configured host (defaultgitlab.com) in this order:
- Token environment variable —
GITLAB_TOKEN, thenGITLAB_ACCESS_TOKEN, thenOAUTH_TOKEN(glab’s precedence order). The first non-empty value is used, exec-free, and takes precedence over any glab credential. - glab (
glab auth credential-helper) — when no token env var is set, Cynative delegates to the pinnedglabbinary (requires glab v1.85.2+), which readsconfig.ymlor the OS keyring, refreshes an expired OAuth token, and prints the credential as JSON.
GITLAB_TOKEN— first-precedence token.GITLAB_ACCESS_TOKEN— second-precedence token.OAUTH_TOKEN— third-precedence token.GLAB_CONFIG_DIR— exclusive override of glab’s config directory.XDG_CONFIG_HOME— adds$XDG_CONFIG_HOME/glab-cli/config.ymlas a config location.
glab binary is missing or too old, the connector is skipped loudly with a steer to install/upgrade glab or set GITLAB_TOKEN.
Registration and validation: When a token is discovered, Cynative validates it live at startup with a dial-guarded GET /api/v4/user before registering. An invalid, expired, or unreachable token shows the connector as unavailable with a reason rather than registering and failing every request.
GitLab 18.9 or later is required for self-managed instances (when using api_reference; the connector itself still registers but api_reference is unavailable for older instances).
References:
- GitLab CLI (glab) —
GITLAB_TOKEN,GLAB_CONFIG_DIR;glab auth loginandglab auth credential-helper. - GitLab personal access token scopes —
read_api(least-privilege read),api(full),read_repository,read_user.
Target selection
The GitLab connector targets GitLab SaaS —https://gitlab.com, REST API /api/v4 — by default. The instance is chosen by Cynative config (connectors.gitlab.host, default gitlab.com) and host-pinned. The target is not selected per request; the URL must match the served host.
To point at a self-managed instance: set connectors.gitlab.host: gitlab.example.com (or CYNATIVE_CONNECTORS_GITLAB_HOST). Optionally set connectors.gitlab.api_host when API calls go to a different host than the login host, append :port for a non-443 instance, set allow_private_network: true for a private network, and ca_cert for a private CA.
Request usage
Useauth_provider: "gitlab". No connector-specific auth object is required.
gitlab.com with your configured host (or api_host).
Hardening
Host and port pinning
Host pinning allows only the configuredhost (default gitlab.com), or api_host when set. The TLS port is pinned too — the request URL’s port must match the configured port (or 443 when none is configured). Redirects are never followed.
The connector serves the /api/v4 REST API only. A request whose path is not under /api/v4 is not category-classifiable and fails closed (ErrUnclassifiable).
Per-category exposure classification
The in-process classifier resolves each REST request to its GitLab category and required access level (read or write), then allows it only when the configuredconnectors.gitlab.permissions ceiling permits that level for that category.
- The check runs before the token is attached.
- Reads are
GET,HEAD,OPTIONS(plus thePOST /api/v4/markdowndocumentation-render endpoint); everything else is a write. - The
ci-variablescategory is denied by the secure baseline (even for reads) because its read endpoints return plaintext CI/CD variable values. Any OpenAPI template whose path contains avariablessegment is mapped to theci-variablescategory at table-distillation time. - The GraphQL API (
/api/graphql) is not supported and is always denied. - A path with a
.or..segment, raw or percent-encoded, is denied.
Model-supplied-credential rejection
The connector is the sole setter of credential material. The following are rejected:Private-Token, Job-Token, Deploy-Token, X-Gitlab-Static-Object-Token, Authorization, Proxy-Authorization, X-Ms-Authorization-Auxiliary, and Cookie headers; URL userinfo; the GitLab request-parameter credentials token, private_token, access_token, job_token (in query string, urlencoded, multipart, or JSON body); the feed_token / rss_token feed credentials; and the sudo impersonation control. After all checks pass, Cynative injects Authorization: Bearer <token>.
Dial-time IP authorization
By default, internal IP ranges (RFC1918, loopback, link-local including cloud metadata, ULA, IPv4-mapped forms) are denied. Setallow_private_network: true for self-managed GitLab instances on private networks. An unconditional floor remains denied even with the opt-in: loopback, link-local, and all private (ULA) IPv6 (fc00::/7) — ULA IPv6 stays denied because every major cloud parks its IPv6 instance-metadata service there.
CA certificate (self-managed with a private CA)
Setconnectors.gitlab.ca_cert to the path of a PEM CA certificate file. skip_tls_verify is not supported — TLS validation cannot be bypassed.
Cynative configuration
Target and connection settings
host is the login host (the key glab uses in config.yml). Append :port to either host or api_host for a non-443 instance (e.g. host: gitlab.internal:8443).
Exposure and authorization
connectors.gitlab.permissions is a category → read|write|none ceiling. Omit it entirely for the secure default (read everything except ci-variables). write implies read; none denies even reads.
default=write, an opened ci-variables, or any category:write override), the startup inventory line is loud (⚠).
Defense at a glance
Limitations
- CI job tokens (endpoint-restricted) are out of scope. Cynative authenticates via
Authorization: Bearer, which accepts PATs, project/group access tokens, and OAuth tokens. - The category routing table needs egress to
gitlab.com. With no network and no local cache the connector fails closed. - Container Registry and Pages use separate hosts and authentication paths not covered by this connector.
- Subpath-mounted installations (e.g.
https://example.com/gitlab/) are not supported. - A glab credential requires the
glabbinary (v1.85.2+) onPATH. SetGITLAB_TOKENfor a fully exec-free path. - One instance per run. Cynative registers at most one GitLab provider per session.
- No runtime credential downscoping. The token’s scopes are fixed at issue time. The
permissionsceiling narrows what Cynative will attempt but never expands the token’s own scopes. - Private (ULA) IPv6 instances are unsupported even with
allow_private_network: true. Front a self-managed instance with an RFC1918 IPv4 or global-unicast IPv6 address instead. - A literal
tokenfield in a request body is rejected. GitLab readsparams[:token](the pipeline-trigger credential) from any body encoding, so any model-suppliedtokenfield fails closed. Use the Bearer-authenticatedPOST /projects/:id/pipelineendpoint instead of the trigger endpoint. skip_tls_verifyis not supported. Useca_certfor self-managed instances with a private CA.

