
GitLab
Application Security- Overview
- Setup
- Data & mappings
- Operations & API
- Changelog
The GitLab connector integrates with the GitLab DevSecOps platform to synchronize security and asset data. It connects via the GitLab GraphQL API to fetch projects, repositories, packages, users, and vulnerability findings (SAST, dependency scanning, and secret detection).
Data retrieved from GitLab
| Connector Object | Required | Maps to Data Model |
|---|---|---|
| Code Project | Yes | Code Project |
| Code Repository | Yes | Code Repository |
| Package | Yes | Package |
| Person | Yes | Person |
| Static Code Finding | Yes | Static Code Finding |
| Static Code Finding Definition | Yes | Static Code Finding Definition |
| Secret Detection Finding | Yes | Static Code Finding |
| Secret Detection Finding Definition | Yes | Static Code Finding Definition |
| Open Source Finding | Yes | Open Source Finding |
| Open Source Finding Definition | Yes | Open Source Finding Definition |
Model relationships
For detailed steps on how to view the data retrieved from GitLab in the Brinqa Platform, see How to view your data.
This mapping is implemented once in BaseFinding and therefore applies identically to all three
finding types — Static Code Finding, Secret Detection Finding, and Open Source Finding.
Connection settings
When setting up a data integration, select GitLab from the Connector dropdown and provide the following:
| Setting | Required | Default | Description |
|---|---|---|---|
| API URL | No | https://gitlab.com | GitLab Api URL |
| Access token | Yes | — | GitLab personal access token |
| Page size | No | 100 | Maximum number of records to get per API request |
| Custom Headers | No | — | Custom HTTP headers to include with every request (format: HeaderName=HeaderValue) |
| Parallel requests | No | min(4, cores) | Maximum number of parallel API requests per model sync |
| Security attribute group path | No | — | Optional. Comma-separated full paths of top-level groups whose security attribute categories become selectable SECURITY_ATTRIBUTE_ columns on Code Repository (for example "macys-root,acme-root"). Leave blank to discover categories across all top-level groups the access token belongs to. Requires GitLab Ultimate; ignored on instances without security attributes. |
Authentication
The connector authenticates using a Personal Access Token (PAT) with the GitLab API.
Endpoint
| Method | URL |
|---|---|
POST | https://gitlab.com/api/graphql |
Request Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer <access_token> |
Request Body
The connector communicates with GitLab using the GraphQL API. Every request is a POST to /api/graphql with a JSON body containing a query and optional variables. The connection test issues the following minimal query:
{
"query": "{ projects(first: 1) { nodes { id } } }",
"variables": {}
}
Sample Response
{
"data": {
"projects": {
"nodes": [
{ "id": "gid://gitlab/Project/12345678" }
]
}
}
}
Response Fields
| Field | Description |
|---|---|
data | Container for the requested GraphQL result set. A populated data object with no errors indicates a successful, authenticated request. |
errors | Present only when the query fails (e.g. invalid token or insufficient scope). Used by the connector to surface a connection error. |
Usage
All subsequent API requests include the personal access token as a Bearer token:
Authorization: Bearer <access_token>
The token requires the read_api scope at minimum. For vulnerability data, read_vulnerability is also required.
Sync Behavior
Each sync is a full sync. The connector does not maintain a sync token and does not apply an incremental since filter to its GraphQL queries, so every run re-fetches the complete set of records for each enabled model.
How to obtain GitLab credentials
Obtain a GitLab access token
For the GitLab connector to access the GitLab API, you must provide a project access token. To obtain an access token, follow these steps:
-
Log in to your organization's GitLab portal as an administrator.
-
Navigate to the GitLab project that you want to integrate into the Brinqa Platform.
-
Navigate to Settings > Access Tokens.
-
Click Add new token.
Complete the following fields:
-
Token name: Provide a name for the token.
-
Token description: Provide a description for the token.
-
Expiration date: Set an expiry date for the token.
-
Select a role: Click the dropdown and select the Developer role, as this is the minimum level of access required to retrieve data from the GitLab API.
-
Select scopes: Select the following scopes, as these are the minimum scopes required to retrieve data from the GitLab API:
- read_api
- read_registry
- read_repository

-
-
Click Create project access token.
Your new access token displays. You can not view the token again. Copy and save it to a safe and secure location.
Note: If you do not have permissions to create an access token, contact your GitLab administrator. For additional information, see GitLab documentation on Access Tokens, Projects, and Permissions and Roles.
Attribute mappings
Expand the sections below to view the mappings between the source and the Brinqa data model attributes:
Code Project
| Source Field Name | SDM Attribute |
|---|---|
allowMergeOnSkippedPipeline | ALLOW_MERGE_ON_SKIPPED_PIPELINE |
archived | ARCHIVED |
autocloseReferencedIssues | AUTO_CLOSE_REFERENCED_ISSUES |
avatarUrl | AVATAR_URL |
ciCdSettings.groupRunnersEnabled | GROUP_RUNNERS_ENABLED |
ciCdSettings.jobTokenScopeEnabled | CI_JOB_TOKEN_SCOPE_ENABLED |
ciCdSettings.keepLatestArtifact | KEEP_LATEST_ARTIFACT |
ciConfigPathOrDefault | CI_CONFIG_PATH |
containerRegistryEnabled | CONTAINER_REGISTRY_ENABLED |
createdAt | SOURCE_CREATED_DATE |
| Derived | CATEGORIES |
description | DESCRIPTION |
forkingAccessLevel.stringValue | FORKING_ACCESS_LEVEL |
forksCount | FORKS_COUNT |
fullPath | PATH_WITH_NAMESPACE |
| Hardcoded | SOURCE_STATUS |
httpUrlToRepo | HTTP_URL |
id | UID |
importStatus | IMPORT_STATUS |
issuesAccessLevel.stringValue | ISSUES_ACCESS_LEVEL |
issuesEnabled | ISSUES_ENABLED |
jobsEnabled | JOBS_ENABLED |
labels | LABELS |
lastActivityAt | LAST_SEEN |
lfsEnabled | LFS_ENABLED |
mergeCommitTemplate | MERGE_COMMIT_TEMPLATE |
mergeRequestsAccessLevel.stringValue | MERGE_REQUESTS_ACCESS_LEVEL |
mergeRequestsEnabled | MERGE_REQUESTS_ENABLED |
name | NAME |
namespace | NAMESPACE |
namespace.rootNamespace.fullPath | TOP_LEVEL_GROUP_FULL_PATH |
namespace.rootNamespace.id | TOP_LEVEL_GROUP_ID |
namespace.rootNamespace.name | TOP_LEVEL_GROUP_NAME |
namespace.rootNamespace.webUrl | TOP_LEVEL_GROUP_WEB_URL |
nameWithNamespace | NAME_WITH_NAMESPACE |
onlyAllowMergeIfAllDiscussionsAreResolved | ONLY_ALLOW_MERGE_IF_ALL_DISCUSSIONS_ARE_RESOLVED |
onlyAllowMergeIfPipelineSucceeds | ONLY_ALLOW_MERGE_IF_PIPELINE_SUCCEEDS |
openIssuesCount | OPEN_ISSUES_COUNT |
path | PATH |
printingMergeRequestLinkEnabled | PRINTING_MERGE_REQUEST_LINK_ENABLED |
publicJobs | PUBLIC_JOBS |
removeSourceBranchAfterMerge | REMOVE_SOURCE_BRANCH_AFTER_MERGE |
repository.rootRef | DEFAULT_BRANCH |
requestAccessEnabled | REQUEST_ACCESS_ENABLED |
securityAttributes[] | SECURITY_ATTRIBUTE_{CATEGORY} |
serviceDeskEnabled | SERVICE_DESK_ENABLED |
sharedRunnersEnabled | SHARED_RUNNERS_ENABLED |
snippetsEnabled | SNIPPETS_ENABLED |
squashCommitTemplate | SQUASH_COMMIT_TEMPLATE |
sshUrlToRepo | SSH_URL |
starCount | STAR_COUNT |
suggestionCommitMessage | SUGGESTION_COMMIT_MESSAGE |
| Sync timestamp | LAST_CAPTURED |
topics | TAGS |
topics | TOPICS |
updatedAt | SOURCE_LAST_MODIFIED |
visibility | VISIBILITY |
webUrl | URL |
webUrl | WEB_URL |
wikiEnabled | WIKI_ENABLED |
Code Repository
| Source Field Name | SDM Attribute |
|---|---|
| Default | STATUS |
| Derived | CATEGORIES |
id | UID |
mode | MODE |
name | NAME |
path | PATH |
| Sync timestamp | LAST_CAPTURED |
type | REPO_TYPE |
Package
| Source Field Name | SDM Attribute |
|---|---|
_links.webPath | LINKS_WEB_PATH |
createdAt | SOURCE_CREATED_DATE |
id | UID |
name | NAME |
normalizeAssetStatus(status) | SOURCE_STATUS |
packageType | CATEGORIES |
pipeline.createdAt | PIPELINE_CREATED_AT |
pipeline.iid | PIPELINE_IID |
pipeline.projectId | PIPELINE_PROJECT_ID |
pipeline.ref | PIPELINE_REF |
pipeline.sha | PIPELINE_SHA |
pipeline.source | PIPELINE_SOURCE |
pipeline.status | PIPELINE_STATUS |
pipeline.user.username | PIPELINE_USERNAME |
pipelines | PIPELINES |
pipelines.id | PIPELINE_ID |
pipelines.updatedAt | PIPELINE_UPDATED_AT |
pipelines.user.id | PIPELINE_USER_ID |
status | PACKAGE_STATUS |
| Sync timestamp | LAST_CAPTURED |
tags | TAGS |
version | LATEST_VERSION |
Person
| Source Field Name | SDM Attribute |
|---|---|
accessLevel.integerValue | ACCESS_LEVEL |
createdAt | SOURCE_CREATED_DATE |
createdBy.id | CREATED_BY |
createdBy.username | OWNER |
expiresAt | EXPIRES_AT |
membershipState | MEMBERSHIP_STATE |
| Sync timestamp | LAST_CAPTURED |
user.avatarUrl | AVATAR_URL |
user.id | UID |
user.name | NAME |
user.state | STATE |
user.username | USERNAME |
user.webUrl | WEB_URL |
Static Code Finding
| Source Field Name | SDM Attribute |
|---|---|
dismissalReason | DISMISSAL_REASON |
falsePositive | FALSE_POSITIVE |
id | UID |
location.file | PATH |
location.startLine | LOCATION_START_LINE |
location.vulnerableClass | LOCATION_CLASS |
location.vulnerableMethod | LOCATION_METHOD |
| MD5 of title + CVE/CWE identifiers | TYPE |
project.id | TARGETS |
scanner.externalId | SCANNER_EXTERNAL_ID |
scanner.name | SCANNER_NAME |
scanner.vendor | SCANNER_VENDOR |
state | PROVIDER_STATUS |
| state + dismissalReason | SOURCE_STATUS |
| Sync timestamp | LAST_CAPTURED |
Static Code Finding Definition
| Source Field Name | SDM Attribute |
|---|---|
description | DESCRIPTION |
getFindingSeverityScore(severity) | SEVERITY_SCORE |
identifiers[].externalId (where externalType=cve) | CVE_IDS |
identifiers[].externalId (where externalType=cwe) | CWE_IDS |
identifiers[].url | REFERENCES |
| MD5 of title + CVE/CWE identifiers | UID |
normalizeFindingSeverity(severity) | SEVERITY |
reportType | CATEGORIES |
| Same as CVE_IDS | CVE_RECORDS |
| Same as CWE_IDS | WEAKNESSES |
severity | SOURCE_SEVERITY |
solution | RECOMMENDATION |
| Sync timestamp | LAST_CAPTURED |
title | NAME |
Secret Detection Finding
| Source Field Name | SDM Attribute |
|---|---|
dismissalReason | DISMISSAL_REASON |
falsePositive | FALSE_POSITIVE |
id | UID |
location.file | PATH |
location.startLine | LOCATION_START_LINE |
| MD5 of title + CVE/CWE identifiers | TYPE |
project.id | TARGETS |
scanner.externalId | SCANNER_EXTERNAL_ID |
scanner.name | SCANNER_NAME |
scanner.vendor | SCANNER_VENDOR |
state | PROVIDER_STATUS |
| state + dismissalReason | SOURCE_STATUS |
| Sync timestamp | LAST_CAPTURED |
Secret Detection Finding Definition
| Source Field Name | SDM Attribute |
|---|---|
description | DESCRIPTION |
getFindingSeverityScore(severity) | SEVERITY_SCORE |
identifiers[].externalId (where externalType=cve) | CVE_IDS |
identifiers[].externalId (where externalType=cwe) | CWE_IDS |
identifiers[].url | REFERENCES |
| MD5 of title + CVE/CWE identifiers | UID |
normalizeFindingSeverity(severity) | SEVERITY |
reportType | CATEGORIES |
| Same as CVE_IDS | CVE_RECORDS |
| Same as CWE_IDS | WEAKNESSES |
severity | SOURCE_SEVERITY |
solution | RECOMMENDATION |
| Sync timestamp | LAST_CAPTURED |
title | NAME |
Open Source Finding
| Source Field Name | SDM Attribute |
|---|---|
dismissalReason | DISMISSAL_REASON |
falsePositive | FALSE_POSITIVE |
id | UID |
location.file | PATH |
| MD5 of title + CVE/CWE identifiers | TYPE |
project.id | TARGETS |
scanner.externalId | SCANNER_EXTERNAL_ID |
scanner.name | SCANNER_NAME |
scanner.vendor | SCANNER_VENDOR |
state | PROVIDER_STATUS |
| state + dismissalReason | SOURCE_STATUS |
| Sync timestamp | LAST_CAPTURED |
Open Source Finding Definition
| Source Field Name | SDM Attribute |
|---|---|
description | DESCRIPTION |
getFindingSeverityScore(severity) | SEVERITY_SCORE |
identifiers[].externalId (where externalType=cve) | CVE_IDS |
identifiers[].externalId (where externalType=cwe) | CWE_IDS |
identifiers[].url | REFERENCES |
| MD5 of title + CVE/CWE identifiers | UID |
normalizeFindingSeverity(severity) | SEVERITY |
reportType | CATEGORIES |
| Same as CVE_IDS | CVE_RECORDS |
| Same as CWE_IDS | WEAKNESSES |
severity | SOURCE_SEVERITY |
solution | RECOMMENDATION |
| Sync timestamp | LAST_CAPTURED |
title | NAME |
Operations & API
Expand each connector object to see its operation options, delta-sync behavior, and the API it uses. See connector operation options for how to apply operation options (keys and values are case-sensitive).
Code Project
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
visibility | String | — | Filter by visibility (public, internal, private) |
Delta sync
Not supported. The connector performs a full sync of Code Project on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql - Default filters:
membership: true
query($first: Int!, $after: String, $membership: Boolean, $visibilityLevel: VisibilityLevelsEnum) {
page: projects(first: $first, after: $after, membership: $membership, visibilityLevel: $visibilityLevel) {
pageInfo { endCursor hasNextPage }
nodes {
id name description path
nameWithNamespace
fullPath
createdAt updatedAt lastActivityAt
visibility archived
topics
sshUrlToRepo httpUrlToRepo webUrl
avatarUrl
forksCount starCount
namespace { id name path fullPath webUrl rootNamespace { id name fullPath webUrl } }
repository { exists rootRef }
issuesEnabled mergeRequestsEnabled wikiEnabled
snippetsEnabled serviceDeskEnabled
containerRegistryEnabled jobsEnabled
lfsEnabled sharedRunnersEnabled publicJobs
openIssuesCount importStatus
onlyAllowMergeIfPipelineSucceeds
onlyAllowMergeIfAllDiscussionsAreResolved
allowMergeOnSkippedPipeline
requestAccessEnabled
removeSourceBranchAfterMerge
printingMergeRequestLinkEnabled
autocloseReferencedIssues
mergeCommitTemplate squashCommitTemplate
suggestionCommitMessage
ciConfigPathOrDefault
forkingAccessLevel { stringValue }
issuesAccessLevel { stringValue }
mergeRequestsAccessLevel { stringValue }
ciCdSettings {
groupRunnersEnabled keepLatestArtifact
jobTokenScopeEnabled
}
labels { nodes { title color } }
securityAttributes { nodes { id name securityCategory { name } } }
}
}
}
Code Repository
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
ref | String | — | Git ref (branch/tag) |
path | String | — | Path within repository |
recursive | Boolean | — | Recurse into subdirectories |
Delta sync
Not supported. The connector performs a full sync of Code Repository on every run and applies no incremental date filter.
API
- Type: GraphQL query (two queries per project: trees + blobs) · Endpoint:
POST /api/graphql
query($fullPath: ID!, $first: Int!, $after: String, $ref: String, $path: String, $recursive: Boolean) {
project(fullPath: $fullPath) {
repository {
tree(ref: $ref, path: $path, recursive: $recursive) {
page: trees(first: $first, after: $after) {
pageInfo { endCursor hasNextPage }
nodes { id name path type flatPath }
}
}
}
}
}
Package
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
status | String | — | Filter by status (DEFAULT, HIDDEN, PROCESSING, ERROR, PENDING_DESTRUCTION) |
Delta sync
Not supported. The connector performs a full sync of Package on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql
query($fullPath: ID!, $first: Int!, $after: String, $status: PackageStatus) {
project(fullPath: $fullPath) {
page: packages(first: $first, after: $after, status: $status) {
pageInfo { endCursor hasNextPage }
nodes {
id name version packageType status
createdAt
_links { webPath }
tags { nodes { name } }
pipelines {
nodes {
id iid sha ref status source createdAt updatedAt
project { id }
user { id username }
}
}
}
}
}
}
Person
Operation options
This object does not support any operation options.
Delta sync
Not supported. The connector performs a full sync of Person on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql
query($fullPath: ID!, $first: Int!, $after: String) {
project(fullPath: $fullPath) {
page: projectMembers(first: $first, after: $after) {
pageInfo { endCursor hasNextPage }
nodes {
id accessLevel { integerValue stringValue }
createdAt expiresAt
user { id name username state webUrl avatarUrl }
createdBy { id username }
}
}
}
}
Static Code Finding
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL) |
projectFullPath | String | — | Comma-separated list of GitLab project full paths (e.g., my-group/my-project, my-group/other-project). When set, finding sync is scoped to only the specified projects, bypassing full project enumeration. |
Delta sync
Not supported. The connector performs a full sync of Static Code Finding on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql - Default filters:
reportType: [SAST]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
Static Code Finding Definition
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity |
projectFullPath | String | — | Comma-separated list of GitLab project full paths. When set, scopes finding definition sync to only the specified projects. |
Delta sync
Not supported. The connector performs a full sync of Static Code Finding Definition on every run and applies no incremental date filter.
API
- Type: GraphQL query (reuses Static Code Finding vulnerability data, de-duplicated by title plus CVE/CWE identifiers) · Endpoint:
POST /api/graphql - Default filters:
reportType: [SAST]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
De-duplication is last-write-wins: when several vulnerabilities resolve to the same definition key,
the one processed last supplies the definition's DESCRIPTION, SEVERITY, SOURCE_SEVERITY,
SEVERITY_SCORE, RECOMMENDATION, and REFERENCES. Project syncs are fanned out in parallel, so if
GitLab reports differing values for records sharing a key, which one lands is not guaranteed to be
stable from one sync to the next. NAME and CATEGORIES are unaffected — the title is part of the
key and the report type is fixed per model. REFERENCES is worth calling out: it is drawn from
every identifier GitLab attaches to the record, not just the canonical CVE/CWE identifiers that
form the key, so two records sharing a key can still carry different reference links.
Secret Detection Finding
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL) |
projectFullPath | String | — | Comma-separated list of GitLab project full paths (e.g., my-group/my-project, my-group/other-project). When set, finding sync is scoped to only the specified projects, bypassing full project enumeration. |
Delta sync
Not supported. The connector performs a full sync of Secret Detection Finding on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql - Default filters:
reportType: [SECRET_DETECTION]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
LOCATION_CLASS and LOCATION_METHOD are not populated for this model. The connector's query
requests only file and startLine on the VulnerabilityLocationSecretDetection fragment (see the
query below), so the two class/method attributes — populated for
Static Code Finding, whose fragment does request them — are left unset here.
Secret Detection Finding Definition
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity |
projectFullPath | String | — | Comma-separated list of GitLab project full paths. When set, scopes finding definition sync to only the specified projects. |
Delta sync
Not supported. The connector performs a full sync of Secret Detection Finding Definition on every run and applies no incremental date filter.
API
- Type: GraphQL query (reuses Secret Detection Finding vulnerability data, de-duplicated by title plus CVE/CWE identifiers) · Endpoint:
POST /api/graphql - Default filters:
reportType: [SECRET_DETECTION]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
Secret detection vulnerabilities rarely carry CVE or CWE identifiers, so CVE_IDS, CVE_RECORDS,
CWE_IDS, WEAKNESSES, and REFERENCES are frequently absent on this model. When no identifiers
are returned, the definition key is the hash of the title alone — which means secret detection
findings sharing a title collapse into a single definition more often than the other finding types.
De-duplication is last-write-wins: when several vulnerabilities resolve to the same definition key,
the one processed last supplies the definition's DESCRIPTION, SEVERITY, SOURCE_SEVERITY,
SEVERITY_SCORE, RECOMMENDATION, and REFERENCES. Project syncs are fanned out in parallel, so if
GitLab reports differing values for records sharing a key, which one lands is not guaranteed to be
stable from one sync to the next. NAME and CATEGORIES are unaffected — the title is part of the
key and the report type is fixed per model. REFERENCES is worth calling out: it is drawn from
every identifier GitLab attaches to the record, not just the canonical CVE/CWE identifiers that
form the key, so two records sharing a key can still carry different reference links.
Open Source Finding
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL) |
projectFullPath | String | — | Comma-separated list of GitLab project full paths (e.g., my-group/my-project, my-group/other-project). When set, finding sync is scoped to only the specified projects, bypassing full project enumeration. |
Delta sync
Not supported. The connector performs a full sync of Open Source Finding on every run and applies no incremental date filter.
API
- Type: GraphQL query · Endpoint:
POST /api/graphql - Default filters:
reportType: [DEPENDENCY_SCANNING]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
LOCATION_START_LINE, LOCATION_CLASS, and LOCATION_METHOD are not populated for this model.
GitLab's VulnerabilityLocationDependencyScanning fragment describes the affected dependency rather
than source coordinates, and the connector's query requests file and the dependency object from
it (see the query below), so only PATH is derived from the location.
Open Source Finding Definition
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
severity | String | — | Filter by severity |
projectFullPath | String | — | Comma-separated list of GitLab project full paths. When set, scopes finding definition sync to only the specified projects. |
Delta sync
Not supported. The connector performs a full sync of Open Source Finding Definition on every run and applies no incremental date filter.
API
- Type: GraphQL query (reuses Open Source Finding vulnerability data, de-duplicated by title plus CVE/CWE identifiers) · Endpoint:
POST /api/graphql - Default filters:
reportType: [DEPENDENCY_SCANNING]
query($fullPath: ID!, $first: Int!, $after: String, $reportType: [VulnerabilityReportType!], $severity: [VulnerabilitySeverity!]) {
project(fullPath: $fullPath) {
page: vulnerabilities(first: $first, after: $after, reportType: $reportType, severity: $severity) {
pageInfo { endCursor hasNextPage }
nodes {
id title state dismissalReason severity reportType
scanner { externalId name vendor }
identifiers { name url externalId externalType }
project { id name fullPath }
location {
... on VulnerabilityLocationSast {
file startLine vulnerableClass vulnerableMethod
}
... on VulnerabilityLocationDependencyScanning {
file dependency { package { name } version }
}
... on VulnerabilityLocationSecretDetection {
file startLine
}
}
description solution falsePositive
}
}
}
}
Dependency scanning findings are the richest source of CVE and CWE identifiers, so this model is
where CVE_IDS / CVE_RECORDS / CWE_IDS / WEAKNESSES are most consistently populated. Because
GitLab reuses one generic advisory title across many CVEs, a single title commonly yields several
distinct definition records here — one per CVE/CWE combination.
De-duplication is last-write-wins: when several vulnerabilities resolve to the same definition key,
the one processed last supplies the definition's DESCRIPTION, SEVERITY, SOURCE_SEVERITY,
SEVERITY_SCORE, RECOMMENDATION, and REFERENCES. Project syncs are fanned out in parallel, so if
GitLab reports differing values for records sharing a key, which one lands is not guaranteed to be
stable from one sync to the next. NAME and CATEGORIES are unaffected — the title is part of the
key and the report type is fixed per model. REFERENCES is worth calling out: it is drawn from
every identifier GitLab attaches to the record, not just the canonical CVE/CWE identifiers that
form the key, so two records sharing a key can still carry different reference links.
Changelog
The GitLab connector has undergone the following changes:
| Version | Description | Migration Steps |
|---|---|---|
| 3.1.4 | New Features - Findings now carry a Dismissal Reason attribute — the reason GitLab recorded when a vulnerability was dismissed, present only on dismissed findings. Together with Provider Status, it makes visible exactly which GitLab values produced a given Brinqa status. - Finding Definitions now include a References attribute carrying the reference links GitLab supplies with each identifier (NVD, MITRE, and advisory pages). These links were previously fetched but discarded. Only http and https links are published, since these render as clickable links. Improvements - CVE and CWE identifiers are now accepted only in their canonical formats ( CVE-2021-44228, CWE-89). Malformed values returned by GitLab are dropped instead of being published as identifiers. - Person sync now processes projects in parallel and honors the connector's Parallel requests setting, matching the other project-scoped object types. Previously it fetched project members one project at a time on a single thread no matter how concurrency was configured, so on large GitLab instances Person was by far the slowest object type — on an instance with roughly 25,000 projects a single Person sync ran for hours and had to be cancelled before it could finish. Bug Fixes - A project whose members cannot be read no longer ends the entire Person sync. The failure is logged, that project is skipped, and members from every other project are still collected. Dismissed Vulnerabilities No Longer Reported as Fixed Dismissed vulnerabilities were reported as "Fixed". GitLab has four vulnerability states, but only two Source Status values were reachable before, so a vulnerability a team had dismissed — still present in the code, just accepted, mitigated, or judged a false positive — looked identical to one that had actually been remediated. The connector now reads GitLab's dismissal reason alongside the state and maps it to the appropriate status: Detected, Confirmed, and Resolved findings keep the status they had before; only dismissed findings change. This affects all three finding types — Static Code Finding, Secret Detection Finding, and Open Source Finding. Statuses are corrected on the next sync, with no action required. Any dashboards, filters, or risk rules that relied on dismissed GitLab findings appearing as "Fixed" should be updated to account for the "False positive" and "Risk accepted" statuses. Finding Definitions No Longer Collapse Distinct Vulnerabilities Finding Definitions were identified by the vulnerability title alone. GitLab reuses a single generic title across vulnerabilities that carry different CVE and CWE identifiers (for example, "Unsafe Deserialization in jackson-databind" spans six distinct CVEs), so every vulnerability sharing a title collapsed into one Definition record and only one arbitrary CVE/CWE combination survived — which is why CVE and CWE information appeared missing on Definitions. A Definition is now identified by a generated key derived from its title together with the CVE and CWE identifiers of the vulnerability, so each distinct combination gets its own record with its own identifiers. The title remains the Definition's displayed name. Findings pick up the new key during the same re-sync that rebuilds the Definitions — both sides derive it from the same formula, so no separate finding-side step is needed. Provider Status Visible on Findings Provider Status now appears on all three finding models. The attribute was populated on every finding but missing from the object schema, so GitLab's raw, unmodified vulnerability state was not visible in the UI and could not be compared against the normalized Source Status. Security Attribute Columns No Longer Break Data Warehouse Snapshots GitLab Security Attribute category names are free text, and two distinct categories could produce Code Project columns that the Data Warehouse treated as one. This happened either when punctuation and spacing normalized to the same name ( App Type and App-Type both became SECURITY_ATTRIBUTE_APP_TYPE), or when the names differed only in where a word boundary fell — the Data Warehouse converts a column name to camelCase and then compares case-insensitively, which erases the boundary an underscore carried, so App ID and AppId collided. The duplicate aborted the Data Warehouse snapshot for the entire Code Project model, not just the affected column, and nothing in the connector's own sync reported a problem. The only workaround was renaming the category in GitLab. The connector now checks each generated column name against the same rule the Data Warehouse applies and disambiguates collisions by appending the GitLab category ID: the first colliding category alphabetically keeps its existing column name, and each further one becomes, for example, SECURITY_ATTRIBUTE_APPID_1043 — where 1043 is that category's ID in GitLab, so it is clear which category the column belongs to. Every category syncs under its own column, the collision is recorded in the connector log, and Data Warehouse snapshots complete. Columns for categories that do not collide are unchanged, so existing attribute mappings keep working. Instances that do have colliding categories need the one-time attention described under Migration Required. | • Static Code Finding Definition, Secret Detection Finding Definition, Open Source Finding Definition: the record identifier changes from the vulnerability title to a generated key derived from the title plus its CVE/CWE identifiers. On the first sync after upgrading, Definition records are created under the new identifiers and the previous title-keyed records go stale. Findings pick up the new key in that same sync, so there is no separate finding-side step — Action: re-sync the connector, then purge the stale Finding Definition records for the three models above. Purging is a platform data-management operation on the model, not a connector setting; if it is not available to your account, raise a support request to have the title-keyed records removed. Until the purge runs, both the old and new Definition records are present, so Definition counts read roughly double and reports grouped by Definition show each vulnerability twice. Two things to check before the re-sync. Anything that filters or joins on a Definition's identifier — risk rules, dashboard filters, saved queries, API clients — is holding an old title-keyed value and goes empty the moment the new records land; re-point it at the Definition name, which still carries the vulnerability title unchanged. And if a sync is interrupted partway, the Definition store holds a mix of title-keyed and generated-key records; re-running the sync to completion, then purging, resolves it — no manual cleanup of the partial state is needed. To roll back, downgrade to 3.1.3 and re-sync: the connector returns to keying Definitions by title and rebuilds the title-keyed records. Purge the generated-key records left behind by 3.1.4, and be aware that the collapsing behavior this fix addresses returns with them. • Code Project: only on instances whose GitLab Security Attribute categories collide (see the security-attribute fix above). The later category of a colliding pair now syncs under a column suffixed with its GitLab category ID — a category that previously produced SECURITY_ATTRIBUTE_APPID becomes SECURITY_ATTRIBUTE_APPID_1043, and a pair that previously shared one column now produces two. Data stops flowing to the old column name, so a mapping bound to it goes empty — Action: refresh the Code Project schema (edit the connection and click Next), then map the suffixed column and re-point any attribute mapping that used the old name. Instances with no colliding categories are unaffected and need no action. |
| 3.1.3 | Security Attributes on Code Project Added support for GitLab Security Attributes. The connector discovers security attribute categories (e.g., Application Type, Leader) and syncs each as a multi-valued SECURITY_ATTRIBUTE_<CATEGORY> column on Code Project, where every value is a JSON object pairing the attribute's id and name. Categories are discovered at the top-level group rather than by scanning every project, so schema discovery stays fast on large instances. Requires GitLab Ultimate; on other tiers no columns are added and the sync runs normally. Security Attribute Group Path Setting Added an optional connector setting that scopes security-attribute discovery to one or more comma-separated top-level group paths. Left blank, the connector discovers categories across all top-level groups the access token belongs to. Reading a group's categories requires an appropriate role (Owner, Maintainer, or Security Manager) on that group; groups the token cannot read are skipped without failing the sync. Top-Level Group on Code Project Code Project now includes TOP_LEVEL_GROUP_ID, TOP_LEVEL_GROUP_NAME, TOP_LEVEL_GROUP_FULL_PATH, and TOP_LEVEL_GROUP_WEB_URL, identifying each project's top-level group — which also ties a project back to the group that owns its security attributes. Bug Fixes - Project labels are no longer dropped from Code Project on incremental (cache-served) syncs; they were previously lost when a project was read from the local cache instead of being freshly fetched. | N/A |
| 3.1.2 | Improvements - Custom attributes on the Code Project and Package models now register with the correct cross-connector consolidation priority (via the shared attribute helper), so connector-sourced values are consolidated consistently rather than treated as independent. Bug Fixes - Corrected the Package model's pipeline ID attributes ("Pipeline ID", "Pipeline project ID", "Pipeline user id") from numbers to text. GitLab returns these IDs as strings, so writing them into numeric attributes caused the Package sync to fail with an attribute type mismatch whenever a package had an associated pipeline. ("Pipeline IID" is genuinely numeric and is unchanged.) | • Package: the "Pipeline ID", "Pipeline project ID", and "Pipeline user id" attributes changed from numbers to text. Re-sync the GitLab connector to repopulate packages with the corrected type. |
| 3.1.1 | New Features - Added support for Secret Detection findings. The connector can now independently synchronize GitLab secret detection vulnerabilities (e.g., exposed API keys, tokens, and credentials) as separate Secret Detection Finding and Secret Detection Finding Definition models, enabling customers to selectively include or exclude secret scanning data from their sync configuration. Improvements - Added STATUS attribute to Code Repository model, defaulting to "active". | N/A |
| 3.1.0 | New Features - The connector now retrieves GitLab data through the GitLab GraphQL API, using cursor-based pagination for more reliable and efficient synchronization of projects, repositories, packages, users, and vulnerability findings. - Added a Custom Headers configuration option, letting you attach custom HTTP headers (for example, to satisfy a proxy or gateway) to every request the connector makes to GitLab. Improvements - The Code Project model's attribute set was modernized to align with the data available from the GraphQL API. A number of legacy attributes were dropped and replaced with current GitLab project fields, so project records now reflect GitLab's present-day schema. - The Parallel requests setting now controls the maximum number of parallel API requests per model sync, giving more predictable throughput when several models sync at once. | • Code Project: the project attribute set changed as part of the GraphQL migration, with several legacy attributes removed and replaced. Re-sync the GitLab connector so Code Project records are rebuilt with the current set of attributes and any stale attributes are cleared. |
| 3.0.2 | New Features - Added a Labels attribute to the Code Project model, capturing the labels defined on each GitLab project so they are available for filtering and reporting. | N/A |
| 3.0.1 | Bug Fixes - Corrected the Person model's "Created by" attribute from a number to text. GitLab can return this value in a form that does not fit a numeric attribute, which caused the Person sync to fail with an attribute type mismatch. | • Person: the "Created by" attribute changed from a number to text. Re-sync the GitLab connector to repopulate people with the corrected type. |
| 3.0.0 | Overview The GitLab connector integrates with GitLab to synchronize code projects, repositories, packages, users, and security findings from static code analysis (SAST) and open-source dependency scanning. Category: Application Security Models | N/A |