Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ Exit codes are stable for automation: `0` passed, `1` reached the configured sev
sarif_file: agentguard.sarif
```

### CI integrations

See the tested [GitLab CI example](docs/integrations/gitlab-ci.md) for severity
thresholds, machine-readable reports, artifact retention, and current
limitations.

### Configure and suppress

Create `.agentguard.yml`:
Expand Down
54 changes: 54 additions & 0 deletions docs/integrations/gitlab-ci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# GitLab CI

Add AgentGuard as a GitLab CI job to scan the repository, enforce a severity
threshold, and retain a machine-readable report.

## Example job

Copy [`gitlab-ci.yml`](gitlab-ci.yml) into your project's `.gitlab-ci.yml`, or
merge the `agentguard` job into an existing pipeline:

```yaml
image: python:3.13-slim

stages:
- security

agentguard:
stage: security
before_script:
- python -m pip install --disable-pip-version-check agentguard-sast
script:
- agentguard scan . --format json --output agentguard-report.json --fail-on high
artifacts:
when: always
paths:
- agentguard-report.json
expire_in: 1 week
```

The job installs AgentGuard from PyPI, scans the checkout, and writes the JSON
report to `agentguard-report.json`. `artifacts.when: always` retains the report
even when the severity threshold fails the job. Adjust `expire_in` to match your
project's retention policy.

## Threshold and exit codes

`--fail-on high` exits with status `1` when a High or Critical finding is
present, which makes the GitLab job fail. Use another severity (`critical`,
`medium`, or `low`) to change the gate, or `--fail-on none` to publish the
report without failing on findings.

AgentGuard uses these exit codes:

- `0`: the scan completed and no finding reached the configured threshold;
- `1`: at least one finding reached the threshold;
- `2`: the scan could not complete, for example because of invalid arguments or
an unreadable target.

## Report limitations

The JSON file is an ordinary GitLab job artifact for downloading or processing
in later jobs. AgentGuard does not currently emit GitLab's native SAST report
schema, so this example does not populate GitLab security dashboards or merge
request security widgets.
16 changes: 16 additions & 0 deletions docs/integrations/gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
image: python:3.13-slim

stages:
- security

agentguard:
stage: security
before_script:
- python -m pip install --disable-pip-version-check agentguard-sast
script:
- agentguard scan . --format json --output agentguard-report.json --fail-on high
artifacts:
when: always
paths:
- agentguard-report.json
expire_in: 1 week
16 changes: 16 additions & 0 deletions tests/test_gitlab_ci_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import annotations

from pathlib import Path

import yaml


def test_gitlab_ci_example() -> None:
example = Path("docs/integrations/gitlab-ci.yml")
config = yaml.safe_load(example.read_text(encoding="utf-8"))
job = config["agentguard"]

assert job["stage"] == "security"
assert job["script"] == ["agentguard scan . --format json --output agentguard-report.json --fail-on high"]
assert job["artifacts"]["when"] == "always"
assert "agentguard-report.json" in job["artifacts"]["paths"]