> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# GitLab

> Set up GitLab CI workflow for CodeAnt CI scan.

# CodeAnt CI Scan for GitLab

A GitLab CI/CD configuration to run CodeAnt security and code quality analysis on your repository.

## Features

* 🧠 Automated security and code quality scanning
* 🔍 Deep vulnerability and dependency analysis
* 📊 Comprehensive reports and actionable insights
* ⚡ Fast setup - integrate in under a minute
* 🔄 Supports push, merge requests, and default branch commits

## Quick Start (Recommended)

Add this to your project's `.gitlab-ci.yml` file:

```yaml theme={null}
include:
  - remote: 'https://gitlab.com/codeant-pipelines/ci-scan-gitlab/-/raw/main/.gitlab-ci.yml'

variables:
  ACCESS_TOKEN: "$ACCESS_TOKEN"        # Required - set this in GitLab CI/CD Variables
  SCANNERS: "sast,sca"                 # Optional (default sast,sca)
  INCLUDE_PATHS: "src/,lib/"           # Optional
  EXCLUDE_PATHS: "tests/,docs/"        # Optional
  SCAN_TIMEOUT: "600"                  # Optional (default 300 seconds)
```

This will automatically run the `codeant_scan` job defined in the shared CodeAnt pipeline template.

<Note>
  **Self-hosted GitLab:** The pipeline forwards your instance URL (`CI_SERVER_URL`) to CodeAnt so the token is validated against the correct GitLab server. This happens automatically - no extra configuration is needed. If validation fails with `401 Access token invalid`, confirm `CI_SERVER_URL` resolves to your GitLab instance, or set `BASE_URL` explicitly (e.g. `https://gitlab.your-company.com`).
</Note>

## Setup Guide

### 1. Create a CodeAnt Token

In CodeAnt AI, open the user menu (click your email at the bottom-left) and select **API Tokens**, click **Create token**, and copy the generated token (it starts with `cdt_` and is shown only once). See [API Tokens](/settings/api-tokens) for the full walkthrough. This single token authenticates the scan - you don't need a GitLab access token.

### 2. Add Token to GitLab CI/CD Variables

1. Go to **Settings > CI/CD > Variables**
2. Click **Add Variable**
3. Fill in the details:
   * **Key:** `ACCESS_TOKEN` (this is the variable name the included template reads)
   * **Value:** your CodeAnt token (`cdt_…`)
   * **Protect variable:** Yes (Recommended)
   * **Mask variable:** Yes (Recommended)
4. Click **Add Variable**

### 3. Commit and Push

Once your `.gitlab-ci.yml` file includes the CodeAnt template, push it to your repository. Your next push, merge request, or main branch commit will automatically trigger a scan.

## Advanced Usage

You can customize how CodeAnt scans your repository by overriding variables:

```yaml theme={null}
include:
  - remote: 'https://gitlab.com/codeant-pipelines/ci-scan-gitlab/-/raw/main/.gitlab-ci.yml'

variables:
  ACCESS_TOKEN: "$ACCESS_TOKEN"
  SCANNERS: "sast,sca"                  # Customize scanners (all, sast, sast,secrets, etc.)
  INCLUDE_PATHS: "src/,backend/"
  EXCLUDE_PATHS: "tests/,vendor/"
  SCAN_TIMEOUT: "900"                   # Timeout in seconds
  BASE_URL: "$CI_SERVER_URL"            # GitLab instance URL (auto for SaaS & self-hosted)
```

## Scanner Options

🔍 **Available Scanners:**

The `SCANNERS` variable allows you to customize which security scanners run during analysis:

* **`sast`** - Static Application Security Testing (code vulnerabilities)
* **`sca`** - Software Composition Analysis (dependency vulnerabilities)
* **`secrets`** - Secret detection (API keys, passwords, tokens)
* **`antipatterns`** - Code quality and duplicate code detection
* **`iac`** - Infrastructure as Code security (Terraform, CloudFormation, etc.)
* **`all`** - Run all available scanners

**Default:** If not specified, runs `sast,sca`

**Examples:**

* Run all scanners: `SCANNERS: 'all'`
* Only SAST: `SCANNERS: 'sast'`
* SAST + Secrets: `SCANNERS: 'sast,secrets'`
* Full security suite: `SCANNERS: 'sast,sca,secrets,iac'`

## Quality Gate Enforcement

🚦 **Block the pipeline on the whole-repository posture:**

Pass `--quality-gate` (`-q`) to `start_scan.sh` to turn the scan into an enforced gate. After the scan completes, CodeAnt evaluates the **entire repository** against your thresholds and the script **exits non-zero** if the gate fails - failing the pipeline. This is the Checkmarx / SonarQube-style whole-repo gate, independent of the new-code/PR quality gate.

**Configure thresholds** in **Settings → Code Analysis → Quality Gates** using the **"(Full Code / CI Pipeline)"** metrics (these run only in the pipeline, never on merge requests):

* `(Full Code / CI Pipeline) SAST Security Rating` `≤` `C`
* `(Full Code / CI Pipeline) SCA Security Rating` `≤` `C`
* `(Full Code / CI Pipeline) IaC Security Rating` `≤` `C`
* `(Full Code / CI Pipeline) Duplicate Code Percentage` `>` `30`

Results group into three status checks: **SAST** (app security + IaC), **SCA** (dependencies), and **SCR** (duplicate code). The gate writes `codeant.sarif` (SARIF 2.1.0), `codeant-qg.xml` (JUnit), and `results.json` (full verdict + findings).

<Note>
  `--quality-gate` requires a commit SHA (`-c`) and cannot be combined with `--no-wait` (the gate needs the scan results). Use `--scanners` to scope the gate (e.g. `--scanners "sast,sca"`).
</Note>

```yaml theme={null}
codeant_quality_gate:
  stage: security
  image: alpine:latest
  variables:
    API_BASE: "https://api.codeant.ai"
  before_script:
    - apk add --no-cache curl bash python3
  script:
    - |
      curl -sS -X GET "${API_BASE}/analysis/ci/scan/script/get" --output start_scan.sh.b64
      base64 -d start_scan.sh.b64 > start_scan.sh
      chmod +x start_scan.sh
      bash start_scan.sh \
        -a "$ACCESS_TOKEN" \
        -r "$CI_PROJECT_PATH" \
        -c "$CI_COMMIT_SHA" \
        -s gitlab \
        --scanners "all" \
        --quality-gate \
        -t 600
  artifacts:
    when: always
    reports:
      junit: codeant-qg.xml
    paths:
      - codeant.sarif
      - results.json
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```

## Example Configurations

### Run All Scanners

```yaml theme={null}
include:
  - remote: 'https://gitlab.com/codeant-pipelines/ci-scan-gitlab/-/raw/main/.gitlab-ci.yml'

variables:
  ACCESS_TOKEN: "$ACCESS_TOKEN"
  SCANNERS: "all"  # Runs all scanner types
```

### Security-Focused Scan

```yaml theme={null}
include:
  - remote: 'https://gitlab.com/codeant-pipelines/ci-scan-gitlab/-/raw/main/.gitlab-ci.yml'

variables:
  ACCESS_TOKEN: "$ACCESS_TOKEN"
  SCANNERS: "sast,secrets"  # Only code vulnerabilities and secret detection
```

### Scan on Push and Merge Requests (Default)

```yaml theme={null}
codeant_scan:
  # ... configuration
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_PIPELINE_SOURCE == "push"
```

### Scan Only on Main Branch and Merge Requests

```yaml theme={null}
codeant_scan:
  # ... configuration
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
```

### Scheduled Daily Scan

Create a scheduled pipeline in **CI/CD > Schedules** and use:

```yaml theme={null}
codeant_scan:
  # ... configuration
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
```

### Scan Specific Directories with Security Focus

```yaml theme={null}
codeant_scan:
  image: alpine:latest
  variables:
    SCANNERS: "sast,secrets"
    INCLUDE_PATHS: "src/,backend/"
    EXCLUDE_PATHS: "src/tests/,backend/vendor/"
  # ... rest of configuration
```

### Using a Self-Hosted CodeAnt Instance

```yaml theme={null}
codeant_scan:
  image: alpine:latest
  variables:
    API_BASE: "https://codeant.your-company.com"
    INCLUDE_PATHS: ""
    EXCLUDE_PATHS: ""
  # ... rest of configuration
```

### Increasing Scan Timeout

For large repositories that need more time to complete analysis:

```yaml theme={null}
codeant_scan:
  image: alpine:latest
  timeout: 15m  # GitLab job timeout (prevents job from running too long)
  variables:
    SCAN_TIMEOUT: "600"  # Scan script timeout in seconds (10 minutes)
    INCLUDE_PATHS: ""
    EXCLUDE_PATHS: ""
  # ... rest of configuration
```

**Timeout Options:**

* `timeout: 15m` - GitLab CI job timeout (format: 30s, 5m, 1h, 2h 30m)
* `SCAN_TIMEOUT: "600"` - CodeAnt scan timeout in seconds (default: 300)

**Recommended Values:**

* Samll repos (\< 1000 files): `SCAN_TIMEOUT: "300"` (5 minutes)
* Medium repos (1000-5000 files): `SCAN_TIMEOUT: "600"` (10 minutes)
* Large repos (>5000 files): `SCAN_TIMEOUT: "900"` (15 minutes)

### Multi-Stage Pipeline

Integrate CodeAnt scan with other pipeline stages:

```yaml theme={null}
stages:
  - security
  - test
  - build
  - deploy

codeant_scan:
  stage: security
  image: alpine:latest
  variables:
    API_BASE: "https://api.codeant.ai"
  before_script:
    - apk add --no-cache curl bash python3
  script:
    - |
      curl -sS -X GET "${API_BASE}/analysis/ci/scan/script/get" \
        --output start_scan.sh.b64
      if [ "$API_BASE" = "https://api.codeant.ai" ]; then
        base64 -d start_scan.sh.b64 > start_scan.sh
      else
        mv start_scan.sh.b64 start_scan.sh
      fi
      chmod +x start_scan.sh
      bash start_scan.sh \
        -a "$ACCESS_TOKEN" \
        -r "$CI_PROJECT_PATH" \
        -c "$CI_COMMIT_SHA" \
        -b "$CI_COMMIT_REF_NAME" \
        -s gitlab \
        -i "$INCLUDE_PATHS" \
        -e "$EXCLUDE_PATHS" \
        --scanners "$SCANNERS"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

unit_tests:
  stage: test
  script:
    - npm test

build_app:
  stage: build
  script:
    - npm run build

deploy_production:
  stage: deploy
  script:
    - ./deploy.sh
  only:
    - main
```

## GitLab CI Variables Used

The configuration automatically uses these GitLab predefined variables:

* **CI\_PROJECT\_PATH** - Full path of the repository (e.g., group/project)
* **CI\_COMMIT\_SHA** - The commit SHA being analyzed
* **CI\_COMMIT\_REF\_NAME** - The branch or tag name
* **CI\_PIPELINE\_SOURCE** - The source of the pipeline trigger
* **CI\_DEFAULT\_BRANCH** - The default branch of the project

## Troubleshooting

**Authentication Errors** / `401 Access token invalid`

* Ensure your `ACCESS_TOKEN` holds a valid CodeAnt token (`cdt_…`) that hasn't been revoked
* Check that the token belongs to the same organization as the repository
* Confirm the variable is available (not protected when running on non-protected branches)
* **Self-hosted GitLab:** the token is validated against the GitLab instance reported by `BASE_URL` (default `$CI_SERVER_URL`). A 401 usually means CodeAnt validated against the wrong instance - confirm `CI_SERVER_URL` points to your GitLab server, or set `BASE_URL` explicitly (e.g. `https://gitlab.your-company.com`)

**Scan Failures**

* Verify your repository is accessible
* Check that the API base URL is correct
* Review the pipeline logs for specific error messages
* Ensure GitLab runners can access the CodeAnt API endpoint

**Script Download Issues**

* Verify the `API_BASE` URL is correct
* Check network connectivity and firewall rules
* Ensure the CodeAnt API endpoint is accessible from your GitLab runners

**Pipeline Not Triggering**

* Check that `.gitlab-ci.yml` is in the repository root
* Verify the `rules` section matches your intended triggers
* Review **CI/CD > Pipelines** for error messages
* Validate the YAML syntax using GitLab's CI Lint tool (**CI/CD > Editor > Validate**)

## Support

* 📧 Email: [support@codeant.ai](mailto:support@codeant.ai)
* 📚 Documentation: [https://docs.codeant.ai](https://docs.codeant.ai)
* 🐛 Issues: [GitLab Issues](https://gitlab.com/codeant-pipelines/ci-scan-gitlab)
* 💬 GitLab CI/CD Docs: [https://docs.gitlab.com/ee/ci/](https://docs.gitlab.com/ee/ci/)

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## About CodeAnt

CodeAnt provides automated code analysis and security scanning to help developers build secure, high-quality software. Visit [codeant.ai](https://codeant.ai) to learn more.## Token permission

This pipeline authenticates with a CodeAnt API token (`cdt_…`). If the token is **scoped**, give it the **Codeant CI/CD** role - it covers scans, quality gates, and test-coverage upload - scoped to the repositories this pipeline runs on (or **All repositories**). A token missing the required permission is rejected with an HTTP `403` `token_scope_forbidden` error that names the permission it needs. See [API token permissions](/settings/api-tokens#permissions-and-scopes).
