GitLab Example Queries#
Projects and languages#
List the programming languages detected across GitLab projects:
MATCH (project:GitLabProject)
WHERE project.languages IS NOT NULL
WITH apoc.convert.fromJsonMap(project.languages) AS languages
UNWIND keys(languages) AS language
RETURN DISTINCT language
ORDER BY language
Find projects that report a specific language without requiring APOC:
MATCH (project:GitLabProject)
WHERE project.languages CONTAINS '"Python"'
RETURN project.name, project.languages
The second query performs a string search. Parse languages with
apoc.convert.fromJsonMap() when exact percentages are needed.
CI/CD security#
Find runners that accept untagged jobs from unprotected refs:
MATCH (runner:GitLabRunner)
WHERE runner.run_untagged = true
AND runner.access_level = 'not_protected'
RETURN runner.id, runner.description, runner.runner_type
Find unmasked, unprotected CI/CD variables:
MATCH (variable:GitLabCIVariable)
WHERE variable.protected = false
AND variable.masked = false
RETURN variable.scope_type, variable.key, variable.environment_scope
Find environments that use unprotected variables:
MATCH (environment:GitLabEnvironment)-[:HAS_CI_VARIABLE]->(variable:GitLabCIVariable)
WHERE variable.protected = false
RETURN environment.name, variable.key, variable.environment_scope
Find project includes that are not pinned to an immutable commit:
MATCH (config:GitLabCIConfig)-[:USES_INCLUDE]->(include:GitLabCIInclude)
WHERE include.include_type = 'project'
AND include.is_pinned = false
RETURN config.project_id, include.location, include.ref
Find manually triggerable pipelines that reference protected variables:
MATCH (config:GitLabCIConfig)
WHERE 'manual' IN config.trigger_rules
AND size(config.referenced_protected_variables) > 0
RETURN config.project_id,
config.referenced_protected_variables,
config.trigger_rules
Container registry#
List container images and their tags:
MATCH (repository:GitLabContainerRepository)
-[:REPO_IMAGE]->(tag:GitLabContainerRepositoryTag)
-[:IMAGE]->(image:GitLabContainerImage)
RETURN repository.name,
tag.name,
image.digest,
image.architecture,
image.os
Find multi-architecture images and their platform-specific images:
MATCH (manifest:GitLabContainerImage {type: 'manifest_list'})
-[:CONTAINS_IMAGE]->(image:GitLabContainerImage)
RETURN manifest.digest, image.digest, image.architecture, image.os
Find images with signatures or provenance attestations:
MATCH (attestation:GitLabContainerImageAttestation)
-[:ATTESTS]->(image:GitLabContainerImage)
RETURN image.digest,
attestation.attestation_type,
attestation.predicate_type
Find layers shared by multiple GitLab images:
MATCH (image:GitLabContainerImage)-[:HAS_LAYER]->(layer:GitLabContainerImageLayer)
WITH layer, count(DISTINCT image) AS image_count
WHERE image_count > 1
RETURN layer.diff_id, layer.size, image_count
ORDER BY image_count DESC
Find layers shared between GitLab Container Registry and Amazon ECR:
MATCH (layer:ImageLayer)
MATCH (gitlab_image:GitLabContainerImage)-[:HAS_LAYER]->(layer)
MATCH (ecr_image:AWSECRImage)-[:HAS_LAYER]->(layer)
RETURN layer.diff_id,
count(DISTINCT gitlab_image) AS gitlab_images,
count(DISTINCT ecr_image) AS ecr_images
Trivy integration#
Find Trivy vulnerabilities that affect GitLab container images:
MATCH (finding:TrivyImageFinding)-[:AFFECTS]->(image:GitLabContainerImage)
RETURN finding.name, finding.severity, image.uri, image.digest
ORDER BY finding.severity DESC
Find critical image vulnerabilities and available package fixes:
MATCH (finding:TrivyImageFinding {severity: 'CRITICAL'})
-[:AFFECTS]->(image:GitLabContainerImage)
MATCH (finding)-[:AFFECTS]->(package:PackageVersion)
OPTIONAL MATCH (package)-[:SHOULD_UPDATE_TO]->(fix:TrivyFix)
RETURN finding.name,
image.uri,
package.name,
package.version,
fix.version AS fixed_version