CI/CD Integration
Integrate Auto Offensive into your deployment pipelines to trigger scans, monitor jobs, fetch findings, and download reports programmatically. The page follows the same pattern as the other docs pages so your team can move between CLI, tools, API, and CI/CD references without relearning the layout.
Overview
CI/CD integration is built around a simple flow: authenticate, create a scan job, poll for completion, retrieve the results, and decide whether the pipeline should continue. This is especially useful for gated environments where releases depend on security outcomes.
CI/CD Workflow
The normal integration pattern is a five-step cycle that works with GitHub Actions, GitLab CI, Bitbucket Pipelines, or any custom runner that can call HTTPS APIs.
| Step | Description |
|---|---|
| 01Authenticate | Load the API key from your CI/CD secret manager. |
| 02Trigger Scan | Create a scan job with the target or repository payload. |
| 03Poll Status | Wait until the backend returns a terminal state. |
| 04Fetch Results | Retrieve findings and compare them with your policy threshold. |
| 05Pass or Fail | Decide whether the pipeline should continue, warn, or block. |
Authentication
Every request should send an API key or token in the authorization header. Keep credentials in your CI/CD platform's secret manager rather than checking them into repositories or workflow files.
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/jsonCreate an API key for CI/CD using the CLI or REST API:
# Via CLI
aof apikeys create --project "Web App" --name "ci-deploy" --scopes "scan:submit,scan:read"
# Via REST API
curl -X POST "https://api.auto-offensive.com/api/v1/apikeys/create?project_id=proj_abc123" \
-H "Authorization: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "ci-deploy", "description": "GitHub Actions", "scopes": ["scan:submit", "scan:read"]}'CLI Commands
| Command | Description |
|---|---|
aof scans submit | Create a new scan job from the pipeline. |
aof scans status | Check scan progress and status. |
aof findings list | Fetch normalized findings. |
aof reports download | Download the generated report. |
Triggering a Scan
Create a scan with aof scans submit. The CLI returns a job_id that the pipeline can store and reuse in later steps.
| Field | Type | Required | Description |
|---|---|---|---|
target | string | Depends | Domain, URL, or host for web scanning. |
repository | string | Depends | Repository URL for repository analysis. |
scan_type | string | Yes | Set to web or repository. |
modules | array | No | Select the modules to run for the scan. |
severity_threshold | string | No | Control when the pipeline should fail. |
curl -X POST https://api.auto-offensive.com/scans/advanced/submit \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": "proj-abc123",
"command": "subfinder -d example.com | httpx -sc | nuclei",
"execution_mode": "advanced"
}'Job Status
Use aof scans status --watch to automatically poll. The CLI will block and wait until the job finishes completely.
| Status | Meaning |
|---|---|
| JOB_STATUS_PENDING | Queued and waiting for execution. (Transient — keep polling) |
| JOB_STATUS_QUEUED | In the execution queue. (Transient — keep polling) |
| JOB_STATUS_RUNNING | Currently scanning. (Transient — keep polling) |
| JOB_STATUS_COMPLETED | Finished and ready for result retrieval. (Terminal — stop polling) |
| JOB_STATUS_PARTIAL | Partially completed — some steps succeeded. (Terminal — stop polling) |
| JOB_STATUS_FAILED | Stopped because of an execution error. (Terminal — stop polling) |
| JOB_STATUS_CANCELLED | Manually or programmatically cancelled. (Terminal — stop polling) |
$ aof scans status job_8f3a21cd --watch
[INFO] Job is running... (Elapsed: 45s)
[INFO] Job completed successfully!
Findings: 1 Critical, 3 High, 7 Medium, 12 LowResult Retrieval
Retrieve findings using aof findings list. You can export the results as JSON for downstream automation.
?page=1&limit=50 when the job returns a large finding set.$ aof findings list job_8f3a21cd --format json > results.jsonReport Download
Download reports with aof reports download. You can request a human-readable PDF output to email to stakeholders.
| Parameter | Values | Default |
|---|---|---|
format | pdf · json | pdf |
include_evidence | true · false | false |
curl -X GET \
"https://api.platform.io/scans/jobs/job_8f3a21cd/report?format=pdf" \
-H "Authorization: Bearer $API_KEY" \
--output scan-report.pdfPipeline Example
The pipeline below triggers a repository scan, polls until completion, and fails the build if critical findings are present.
name: Security Scan
on:
push:
branches: [main, develop]
pull_request:
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Install Auto-Offensive CLI
run: curl -sL https://cli.auto-offensive.com/install.sh | bash
- name: Run Security Scan & Quality Gate
env:
AOF_API_KEY: ${{ secrets.AOF_API_KEY }}
run: |
aof scans submit \
--project "${{ vars.AOF_PROJECT_ID }}" \
--target "${{ vars.TARGET_DOMAIN }}" \
--modules "subfinder,httpx,nuclei" \
--severity-threshold "critical,high" \
--watch \
--fail-pipelineSeverity Thresholds
Use severity_threshold to control when the build should fail. This gives teams a practical way to tune security gates by environment.
| Threshold | Pipeline Behaviour |
|---|---|
critical | Fail only when critical issues are found. |
high | Fail on high or critical findings. |
medium | Fail on medium, high, or critical findings. |
low | Fail on any finding. |
| none set | Always pass and use the results for reporting only. |
high for production deployment gates and medium for pre-production environments when you want a better balance between velocity and security.Access Scoping
Requests are always scoped to the authenticated workspace. Pipelines cannot read scans, jobs, or reports from other workspaces, and invalid cross-workspace references should return 403 Forbidden.
Quotas & Rate Limits
Scan submissions are governed by a daily quota and per-minute rate limit. Response headers tell you your current standing:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When you exceed the quota, you receive a 429 Too Many Requests response. Your pipeline should wait until the X-RateLimit-Reset timestamp before retrying.
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705363200
{
"detail": "Daily scan quota exceeded. Resets at 2024-01-16T00:00:00Z"
}Error Handling in Pipelines
| Status | Meaning | Pipeline Action |
|---|---|---|
| 401 | Invalid or expired API key | Abort — check secret configuration |
| 403 | Key not authorized for this project | Abort — verify key scope |
| 429 | Quota or rate limit exceeded | Wait until reset timestamp, then retry |
| 5xx | Server error | Retry with exponential backoff (max 3 attempts) |
- Store API keys in CI/CD secret managers (GitHub Secrets, GitLab CI Variables)
- Rotate keys when team membership changes
- Scope keys to specific projects — avoid broad-access keys
- Use minimum required scopes (scan:submit, scan:read)