GitLab
Discover AI assets in your GitLab projects with the Airia Code Scanner.
Airia discovers AI assets living in your GitLab projects: agent frameworks, model SDK usage, prompt files, workflow definitions, MCP server configurations, and hard-coded LLM keys or endpoints.
GitLab discovery works the same way on GitLab.com and on self-managed instances — the scanner reports the instance's own host, so findings link back to your own domain.
Status
The GitLab connector is released behind a feature flag, so it may not be enabled for your tenant yet. If the GitLab tile under Discover → Connect shows Coming soon and can't be opened, ask your Airia contact to enable it. Ingestion is not gated: once a pipeline is configured, scans are accepted and appear in the inventory regardless of the flag.
How GitLab discovery works
GitLab discovery is powered by the Airia Code Scanner, which runs as a GitLab CI/CD job inside your project. Each scan analyzes the project's contents and reports its findings to your Airia tenant; every scanned project then appears under Discover → Activity feed → Code Scanner, with the discovered code-based agents, and the models they reference, in the inventory.
There is no credential form to fill in on the Airia side, and Airia never connects to GitLab: the scanner authenticates to Airia with an API key you store as a CI/CD variable, and pushes results outward. No inbound access to your instance is required, which is what makes this work for private and network-isolated installations.
The job runs the scanner image directly as its image:, so it needs no Docker-in-Docker and
no privileged runner — a shared runner is enough.
What the scanner detects
| Category | Indicators |
|---|---|
| Agent frameworks | CrewAI, LangGraph, LangChain, and similar framework usage and agent definitions |
| Model SDK usage | Imports and dependencies such as openai, anthropic, azure-ai, google-genai in requirements.txt, package.json, pom.xml, and similar |
| Prompt files | Standalone prompt assets and templates (*.prompt, prompts/ directories, system-prompt strings) |
| LLM keys and endpoints in config | Model API keys and endpoint URLs in .env, config files, or infrastructure-as-code (a security finding as well as an inventory signal) |
| Model artifacts | Model files and references (including hosted model references such as Hugging Face) |
| Workflow files | n8n workflow exports, LangGraph graph definitions, and similar agentic workflow files |
| MCP server configs | Model Context Protocol server manifests and client configurations (for example mcp.json) |
Customer-side setup steps
-
Generate an Airia API key. In Airia: Settings → Developer → API Keys → Generate Key. If the dialog asks for a key Type, keep Service account selected, since the key is shared with your CI pipeline. Name it something like
code-scanner-gitlaband set Scope to All projects. If the dialog asks for Roles, select End User: the scanner only reports findings, which needs a valid key but no particular permission, so the least-privileged role is enough. Click Create, then copy the key — it is shown once, after you click Create. -
Add two CI/CD variables. In the GitLab project: Settings → CI/CD → Variables → Add variable.
Key Value Flags AIRIA_API_URLyour Airia API URL, for example https://api.airia.aion Airia's US cloud (use your instance's API URL on another region or a self-managed instance), with no path and no trailing/— AIRIA_API_TOKENthe API key from step 1 Mask variable Leave Protect variable unchecked unless you only ever scan protected branches: a protected variable is simply absent on other branches, which surfaces as an authentication failure rather than a missing-variable one.
To scan several projects, add the same two variables once at the group level instead of per project.
-
Add the pipeline file. Create
.gitlab-ci.ymlat the repository root, or add the stage and job to an existing one. Use the Pipeline editor (Build → Pipeline editor), which validates the file before you commit it.# Airia Code Scanner stages: - airia-scan airia-code-scan: stage: airia-scan image: name: airiadevops305/airia-code-scanner:latest entrypoint: [""] rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "web" variables: PROVIDER: "GitLab" REPOSITORY_OWNER: "$CI_PROJECT_NAMESPACE" REPOSITORY: "$CI_PROJECT_NAME" REPOSITORY_URL: "$CI_PROJECT_URL" BRANCH: "$CI_COMMIT_REF_NAME" COMMIT_SHA: "$CI_COMMIT_SHA" GITHUB_WORKSPACE: "$CI_PROJECT_DIR" script: - /app/scanner-cli artifacts: when: always paths: - scan-results.json expire_in: 1 week -
Run the pipeline. Committing the file triggers it on the default branch. To start one by hand: Build → Pipelines → Run pipeline.
-
Verify. Open the
airia-code-scanjob log; the scanner prints the repository, branch, commit and workspace it used, and finishes withSuccessfully reported findings to API (status: 200). Thescan-results.jsonartifact is exactly what was sent, which separates a scanning problem from a delivery one.Then in Airia open Discover → Activity feed → Code Scanner: the scanned project appears as a repository with the GitLab provider, and its scans, secret findings included, open from its branch. The discovered agents also land in Discover → Inventory with their detected frameworks and model references. The GitLab page under Discover → Connect only shows this setup guide; it never lists scanned projects.
Notes
PROVIDER: "GitLab"is required, not optional. When the field is absent Airia infers the provider from the repository URL's host, which only recognizesgitlab.comand hostnames beginninggitlab.. A self-managed instance on any other domain is classified correctly only from this value — omit it and the project is filed under GitHub with no error reported.GITHUB_WORKSPACEmust be set to$CI_PROJECT_DIR. The scanner reads the checkout fromGITHUB_WORKSPACE, a name it kept from its GitHub Actions origins. Without this the scanner finds nothing and the scan succeeds with zero findings.- Nested groups are preserved.
CI_PROJECT_NAMESPACEcarries the full group path, so a project under subgroups appears asgroup/subgroup/project. - Air-gapped runners cannot pull from Docker Hub. Mirror the scanner image into your own
container registry and point
image: name:at it. - One repository entry appears per scanned project, with a row for each scanned branch; multiple projects mean multiple entries on the Code Scanner page.
- Discovered code-based agents carry the detected model reference where the scanner can extract one; agents whose model is not declared in code show without a model.
- GitLab CI defaults to a shallow clone (
GIT_DEPTH20), which is all the scanner needs. To scan only when relevant files change, add achanges:clause to the job's rule; note thatchanges:has no exclude form, so list what should trigger a scan.
Repositories hosted elsewhere are covered by the GitHub and Azure DevOps connectors, which use the same scanner and the same push model.