Skip to main content
availability

Deployment: Invicti Platform on-demand

Integrate agentic pentests in CI/CD

Add agentic pentest assessments to your CI/CD pipeline so every delivery gets repeatable security testing, and optionally block a deployment when vulnerabilities meet your severity or confidence policy.

This document explains how to start and monitor an assessment for an existing pentest using the Invicti Scan CLI container, which you configure through environment variables. Scan CLI works with any CI/CD platform that supports Docker. Assessment vulnerabilities and reports remain available in Invicti Platform, and the pipeline can also download reports as build artifacts.

For the DAST equivalent, refer to the Integrate CI-driven scans document.

Scan CLI triggers and monitors the assessment

The assessment runs in Invicti Platform and normally takes the same amount of time as an assessment started from the user interface.

Why this matters​

Without automation, agentic assessments run only when someone remembers to start them. Adding them to your pipeline means every delivery gets tested the same way. A blocking job waits for the results and enforces a severity or confidence policy before deployment. A trigger-only job starts the assessment and lets it continue in Invicti Platform without holding a pipeline runner.

Prerequisites​

Before you begin, make sure you have:

  • Permission to create or update jobs in your CI/CD platform.
  • Docker installed and running on the agent that executes the pipeline.
  • An Invicti Platform account with agentic pentesting enabled and sufficient entitlement and credits to run an assessment.
  • Access to the Invicti Scan CLI image. The public image is invicti/scan-cli:latest.
  • The Agentic Pentests permission with Read, Create, and Update access (or Full) for the user whose API token the pipeline uses. For more information, refer to the Agentic pentests document.
  • An existing pentest in Invicti Platform with its target, authentication, attack types, and other assessment settings configured.
  • Authorization to test the target and accept the applicable agentic-pentest terms.

The CI job needs network access to the Invicti Platform API. The agentic pentesting service tests the target. Scan CLI doesn't launch a DAST scanning agent for this workflow.

Use your region's Invicti Platform URL

The examples in this document use https://platform.invicti.com. If your organization uses another Invicti Platform hostname, such as https://platform-eu.invicti.com or https://platform-ca.invicti.com, replace it in every example and set INVICTI_API_BASE_URL to match.

Generate an API token​

Scan CLI uses an Invicti Platform API token to authenticate.

  1. Click your initials or avatar, and then select User settings.
  2. Select API key.
  3. Copy the existing token, or select Generate new to create one. If you generate a new token, it invalidates the previous one, so update it in every pipeline that uses it.
  4. Store the token in the secret manager provided by your CI/CD platform.

Don't put the token directly in a pipeline file, command history, build log, or container image.

Find your pentest ID​

INVICTI_PENTEST_ID requires the ID of an existing pentest. It doesn't accept a DAST Asset ID, DAST target ID, or assessment ID. Retrieve the ID from the user interface, or use the API if your workflow is API-based.

Retrieve the ID from Invicti Platform​

Open the pentest in Invicti Platform and copy the UUID after /app/pentests/ in the browser URL.

For an assessment URL in this form:

https://platform.invicti.com/app/pentests/<pentest-id>/assessments/<assessment-id>

use <pentest-id>, which is the first UUID. The second UUID identifies one assessment run, so you can't use it as INVICTI_PENTEST_ID.

Retrieve the ID with the API​

To list the pentests visible to your API token, run:

curl -X GET \
"https://platform.invicti.com/api/ai/v1/pentests" \
-H "accept: application/json" \
-H "X-Auth: <your-api-token>"

The production API base path is /api/ai/v1. If your organization uses another Invicti Platform hostname, replace platform.invicti.com with that hostname while keeping the base path.

Match the response object by name and targetUrl, then copy its pentestId value. For example, with jq:

curl --silent --show-error \
"https://platform.invicti.com/api/ai/v1/pentests" \
-H "accept: application/json" \
-H "X-Auth: ${INVICTI_API_TOKEN}" \
| jq -r '.[] | [.name, .targetUrl, .pentestId] | @tsv'

Pentest IDs remain stable, so you can store a non-secret pentest ID with the pipeline configuration and reuse it.

For the complete API definition, open the Octo Agentic Pentesting API in Invicti Platform Swagger.

Configure Scan CLI for an agentic assessment​

Every agentic assessment requires these environment variables:

VariableDescription
INVICTI_API_BASE_URLBase URL of the Invicti Platform instance, for example https://platform.invicti.com.
INVICTI_API_TOKENAPI token stored as a CI/CD secret.
INVICTI_PENTEST_IDUUID of the existing pentest. Its presence selects the agentic assessment workflow.
INVICTI_AGENTIC_PENTEST_TERMS_ACCEPTEDMust be true to confirm the required terms before Scan CLI creates an assessment.

The pentest's current configuration supplies the target, authentication, assessment profile, attack types, source repositories, and reference documents. Scan CLI doesn't require a configuration ID or version number.

Remove DAST-only variables​

An agentic assessment doesn't use a DAST target or scanning agent. Remove these DAST-only settings from the job:

  • INVICTI_TARGET_ID
  • INVICTI_TARGET_URL
  • INVICTI_SCAN_AGENT
  • INVICTI_AGENT_ID
  • INVICTI_AGENT_PATH
  • INVICTI_IMPORT_FILE_PATHS
  • INVICTI_EXCLUDED_PATHS
  • INVICTI_INCREMENTAL_SCAN

Also omit INVICTI_SCAN_PROFILE, or leave it at its default value of Full Scan. You configure agentic attack types and the assessment profile on the pentest in Invicti Platform. Scan CLI rejects incompatible DAST settings instead of silently ignoring them.

Test the setup with a generic Docker example​

The following example waits for the assessment to finish and saves four report formats under ./invicti-results:

mkdir -p invicti-results
docker pull invicti/scan-cli:latest

docker run --rm \
-e INVICTI_API_BASE_URL="https://platform.invicti.com" \
-e INVICTI_API_TOKEN="${INVICTI_API_TOKEN}" \
-e INVICTI_PENTEST_ID="<your-pentest-id>" \
-e INVICTI_AGENTIC_PENTEST_TERMS_ACCEPTED="true" \
-e INVICTI_EXPORT_LIST="PDF:assessment.pdf,HTML:assessment.html,MARKDOWN:assessment.md,JSON:assessment.json" \
-e INVICTI_PUBLIC_DATA_PATH="/home/invicti/publicdata" \
-v "${PWD}/invicti-results:/home/invicti/publicdata" \
invicti/scan-cli:latest

Get more detail in the Scan CLI log​

To see more detail when you troubleshoot a run, set the log level to DEBUG. The default is INFO.

INVICTI_LOG_LEVEL=DEBUG

INVICTI_LOG_LEVEL is also listed in the CI environment variables document, which covers DAST scans.

Choose between blocking and trigger-only runs​

Pick blocking execution when the deployment must wait for the results, and trigger-only execution when the pipeline only needs to start the assessment.

Blocking execution is the default. Scan CLI waits for the assessment to reach COMPLETED, loads its vulnerabilities, evaluates any build-failure policy, generates requested reports, and then exits.

To start the assessment and release the pipeline runner immediately, set the following variable:

INVICTI_TRIGGER_SCAN_ONLY=true

In trigger-only mode, Scan CLI exits after Invicti Platform accepts and starts the assessment. It doesn't wait for vulnerabilities, apply build-failure thresholds, or download reports. Use Invicti Platform or a later API-driven job to monitor the assessment.

A successful trigger-only job doesn't mean the assessment passed

A successful trigger-only job means the assessment started successfully. It doesn't mean the assessment completed successfully or passed a vulnerability policy.

Set timeouts and fail the build on vulnerabilities​

Control how long a blocking run waits, and decide which vulnerabilities stop your deployment.

Choose how long a run waits​

VariableDefaultDescription
INVICTI_SCAN_TIMEOUT2880 minutesMaximum time Scan CLI waits for a blocking assessment. Valid values are 5 through 10080 minutes.
INVICTI_ALLOW_SCAN_COMPLETIONtrueAt the timeout, stop new attacks and allow up to five additional minutes for partial results to finalize. If false, cancel the assessment at the timeout.
INVICTI_STOP_SCAN_BEFORE_NEW_ONEfalseCancel CREATED or RUNNING assessments for the same pentest before creating a new one.

Use INVICTI_STOP_SCAN_BEFORE_NEW_ONE=true only when you want the pipeline to replace an earlier run. It can cancel an assessment started by another user or pipeline that uses the same pentest.

Fail the build when vulnerabilities meet your policy​

A completed assessment exits successfully unless its vulnerabilities meet a threshold you configured.

VariableDescription
INVICTI_MINIMUM_SEVERITYFail when at least one applicable vulnerability has this severity or higher. Accepted values: Critical, High, Medium, Low, and Info.
INVICTI_MINIMUM_CONFIDENCEFail when at least one applicable vulnerability has this confidence percentage or higher. Accepted values: 1 through 100.
INVICTI_IGNORE_IF_VULN_STATUS_IGNOREDWhen true (the default), vulnerabilities marked as false positives don't fail the job.

When you set both severity and confidence, a vulnerability must meet both thresholds to fail the job. Filtering affects only the Scan CLI exit decision. It doesn't change vulnerabilities stored in Invicti Platform or remove them from reports.

For example, to fail the job on any vulnerability with a severity of High or higher and a confidence of at least 80 percent:

INVICTI_MINIMUM_SEVERITY=High
INVICTI_MINIMUM_CONFIDENCE=80

Publish reports as build artifacts​

Keep the assessment results with your build so reviewers can open them without signing in to Invicti Platform. Agentic assessments support PDF, HTML, MARKDOWN, and JSON reports.

VariableDescription
INVICTI_REPORT_TEMPLATEReport format to generate, named with the conventional pattern report.<extension>. For example, PDF creates report.pdf.
INVICTI_EXPORT_LISTComma-separated Format:FileName pairs, for example PDF:assessment.pdf,JSON:assessment.json.
INVICTI_PUBLIC_DATA_PATHDirectory where Scan CLI writes downloaded artifacts. In the container, the default is /home/invicti/publicdata.

Artifact names in INVICTI_EXPORT_LIST must be plain file names without directory components. To place artifacts in a CI workspace, mount or map the whole INVICTI_PUBLIC_DATA_PATH directory.

If INVICTI_REPORT_TEMPLATE=PDF and INVICTI_EXPORT_LIST also contains PDF:assessment.pdf, Scan CLI writes both report.pdf and assessment.pdf without creating the report twice.

Scan CLI logs a report-generation or download error but doesn't change a successful assessment into a failed job. Configure the CI platform to publish the artifact directory with when: always or its equivalent so logs and any successfully generated formats remain available.

Add Scan CLI to your pipeline​

Store the API token in the CI/CD platform's secret manager. Pentest IDs are identifiers rather than credentials, so you can store them as ordinary pipeline variables. To see an example job, open the tab for your CI/CD platform.

name: Invicti agentic assessment

on:
workflow_dispatch: {}
push:
branches: [main]

jobs:
agentic-assessment:
runs-on: ubuntu-latest
container:
image: invicti/scan-cli:latest
env:
INVICTI_API_BASE_URL: "https://platform.invicti.com"
INVICTI_API_TOKEN: ${{ secrets.INVICTI_API_TOKEN }}
INVICTI_PENTEST_ID: "<your-pentest-id>"
INVICTI_AGENTIC_PENTEST_TERMS_ACCEPTED: "true"
INVICTI_MINIMUM_SEVERITY: "High"
INVICTI_EXPORT_LIST: "PDF:assessment.pdf,JSON:assessment.json"
INVICTI_PUBLIC_DATA_PATH: ${{ github.workspace }}/invicti-results
steps:
- name: Run agentic assessment
run: /home/invicti/scancli/ScanCLI

- name: Upload assessment reports
if: always()
uses: actions/upload-artifact@v4
with:
name: invicti-agentic-assessment
path: invicti-results/
if-no-files-found: ignore
retention-days: 7

Monitor a run and recover from interruptions​

For a blocking run, Scan CLI performs these actions:

  1. Authenticates with Invicti Platform.
  2. Retrieves the selected pentest and displays its name, ID, and target URL.
  3. Creates and starts a new assessment using the pentest's current configuration.
  4. Reports the assessment status while it's running.
  5. Retrieves and displays vulnerabilities after the assessment completes.
  6. Applies any configured build-failure conditions.
  7. Generates and downloads requested reports.

The console output includes the new assessment ID. Use that ID to locate the run under Pentests in Invicti Platform.

Each run behaves like Start with current configuration in the user interface. It reruns the pentest with its saved configuration and doesn't create a new version. For more information, refer to the Manage agentic pentests document.

Scan CLI returns exit code 0 when the workflow completes and no vulnerability policy requires failure. It returns exit code 1 for configuration, authentication, platform, terminal assessment, timeout, or vulnerability-policy failures.

If the CI job or Scan CLI process stops​

The assessment runs in Invicti Platform, not in the Scan CLI process. If the runner crashes, the job terminates, or Scan CLI stops forcibly after the assessment starts, the platform assessment continues running. Open the pentest in Invicti Platform to monitor, stop, or cancel the orphaned assessment.

Starting Scan CLI again creates another assessment by default. Set INVICTI_STOP_SCAN_BEFORE_NEW_ONE=true only when you expect the replacement job to cancel any CREATED or RUNNING assessment for the same pentest.

If someone stops the assessment in Invicti Platform​

When a blocking Scan CLI run observes that an external stop has moved the assessment to STOPPING, it continues polling while Invicti Platform finalizes partial results. If the assessment then reaches COMPLETED, Scan CLI processes the available vulnerabilities, generates requested reports, applies the vulnerability policy, and exits normally.

If the assessment instead reaches CANCELLED or FAILED, Scan CLI treats that terminal status as an execution failure and returns a nonzero exit code.

Keep your pipeline safe and predictable​

  • Run an agentic assessment against a dedicated test or staging environment, not an unapproved production target.
  • Keep the pentest configuration in Invicti Platform current. Each CI run uses the current configuration at the time Scan CLI creates the assessment.
  • Store the API token only in the CI/CD platform's secret manager, and restrict which branches and users can access it.
  • Protect jobs that set INVICTI_AGENTIC_PENTEST_TERMS_ACCEPTED=true so untrusted pull requests can't start assessments.
  • Use pipeline concurrency controls to prevent duplicate assessments for the same commit or environment.
  • Choose a timeout that reflects the configured assessment scope. Avoid trigger-only mode when vulnerabilities must block the deployment.
  • Publish reports with an always-run artifact step, because a vulnerability threshold can intentionally make the assessment job fail after Scan CLI generates the reports.
  • Use INVICTI_STOP_SCAN_BEFORE_NEW_ONE=true only when canceling another active assessment is the behavior you want.

Troubleshooting​

The assessment doesn't start because of credits

The job fails when it can't start the assessment because your organization doesn't have enough credits. Check your balance and credit term, and contact your CSM to add credits or renew the term. For details, refer to Credits.

Pentest not found
  • Confirm INVICTI_PENTEST_ID contains a pentest ID, not a DAST target ID or assessment ID.
  • If you copied an assessment URL, use the first UUID after /app/pentests/.
  • Call GET /api/ai/v1/pentests with the same API token and confirm the pentest appears in the response.
  • Confirm the token belongs to an organization and user that can access the pentest.
Agentic-pentest terms aren't accepted

Set:

INVICTI_AGENTIC_PENTEST_TERMS_ACCEPTED=true

Confirm that your organization has authorized the assessment and allows the CI job to make this acknowledgment.

Scan CLI rejects a DAST setting

Remove DAST-only variables such as INVICTI_TARGET_ID, INVICTI_TARGET_URL, INVICTI_SCAN_AGENT, and INVICTI_AGENT_ID. Configure target access, authentication, profile, and attack types on the pentest in Invicti Platform.

The assessment started but the CI job is still running

Blocking mode waits for a terminal assessment status. Review the assessment in Invicti Platform and confirm the target is reachable. If the job should only start the assessment, set INVICTI_TRIGGER_SCAN_ONLY=true.

If the job must remain blocking, adjust INVICTI_SCAN_TIMEOUT. When the run reaches the timeout and INVICTI_ALLOW_SCAN_COMPLETION=true, Scan CLI stops new attacks and allows up to five minutes for partial results to finalize.

The CI job stopped but the assessment is still running

This is normal after the assessment has started. Ending the local Scan CLI process doesn't stop the platform-side assessment. Open the pentest in Invicti Platform and stop or cancel the active assessment. Before rerunning the pipeline, confirm that no assessment is active to avoid starting an unintended duplicate.

The pipeline failed after Scan CLI displayed vulnerabilities

Review INVICTI_MINIMUM_SEVERITY, INVICTI_MINIMUM_CONFIDENCE, and INVICTI_IGNORE_IF_VULN_STATUS_IGNORED. A nonzero exit caused by a vulnerability threshold means the assessment completed, but its results didn't satisfy the pipeline policy.

Reports are missing
  • Scan CLI generates reports only in blocking mode after the assessment completes.
  • Confirm INVICTI_REPORT_TEMPLATE or INVICTI_EXPORT_LIST contains a supported format: PDF, HTML, MARKDOWN, or JSON.
  • Confirm INVICTI_PUBLIC_DATA_PATH exists and is writable by the container user.
  • When using Docker, mount INVICTI_PUBLIC_DATA_PATH to a directory retained by the CI/CD platform.
  • Review the Scan CLI log, and set INVICTI_LOG_LEVEL=DEBUG for more detail. Scan CLI logs report failures but doesn't change the exit code of a successful assessment.
Invicti Platform rejects the API token or authentication fails
  • Confirm the token is current and nobody has regenerated or revoked it.
  • Confirm INVICTI_API_BASE_URL points to the same Invicti Platform instance where the token and pentest exist.
  • Check that the CI job can reach the platform URL over HTTPS.
  • Check the secret value for unintended spaces, quotes, or line breaks.

Need help?​

Invicti Support team is ready to provide you with technical help. Go to Help Center

Was this page useful?