Skip to main content

New CLI

Overview​

The Conviso CLI is a command-line interface for interacting with the Conviso Platform through GraphQL.

It is designed for:

  • local operational workflows;
  • security automation;
  • CI/CD execution;
  • bulk import and export tasks.

Compatibility Note: All examples below use cvs (the recommended short alias). You can also use conviso instead — both commands work identically:

cvs projects list # Recommended (shorter)
conviso projects list # Also works (fully compatible)

Repository:

Requirements​

Install​

pip install conviso-cli
cvs --version

Option 2: From Source (Development)​

git clone https://github.com/convisolabs/conviso-cli.git
cd conviso-cli
pip install -e .
cvs --version

Authentication​

cvs auth login

This will prompt for your API key and save it securely to ~/.config/cvs/credentials.

Using Environment Variables​

Alternatively, set your API key in your shell or .env file:

export CONVISO_API_KEY="<your_api_key>"

Or in a local .env file:

echo "CONVISO_API_KEY=<your_api_key>" > .env

Priority Order​

The CLI looks for API key in this order:

  1. CONVISO_API_KEY environment variable
  2. .env file in current directory
  3. ~/.config/cvs/credentials (saved by cvs auth login)

Check Login Status​

cvs auth whoami

Update CLI​

pip install --upgrade conviso-cli

Built-in upgrade command (for development installations):

cvs upgrade

Command Pattern​

Most commands follow:

cvs <group> <action> [options]

Or use the shorter alias:

cvs <group> <action> [options]

Common command groups currently documented in the CLI repository include:

  • projects
  • assets
  • requirements
  • tasks
  • vulns
  • sbom
  • bulk
  • accesscontrol

The top-level CLI also exposes:

  • upgrade

Output and Pagination​

Many list commands support options such as:

  • --all to fetch all pages
  • --page and --per-page or --limit for pagination control
  • --format table|json|csv
  • --output <file> for file export

Some commands support additional output formats depending on the resource, such as sarif or cyclonedx.

Usage Examples​

The examples below reflect the current usage examples documented in the CLI repository README together with the command tree currently registered in the CLI source code.

Command Catalog​

The currently available command groups and actions are:

  • projects: list, requirements, create, update, status, delete
  • assets: list, create, update, delete
  • requirements: list, project, activities, create, update, delete
  • tasks: create, list, run
  • tasks approvals: list, clear, remove
  • vulns: list, timeline, create, update, check-sca-patches
  • sbom: list, import, check-vulns
  • bulk: assets, requirements, vulns
  • accesscontrol: user-profile, user-teams, bulk-users
  • top-level: upgrade, security-gate

Projects​

List all projects:

cvs projects list --company-id 443 --all

List projects filtered by assignee:

cvs projects list \
--company-id 443 \
--filter assignee=analyst@company.com \
--all

List project requirements and activities:

cvs projects requirements --project-id 12345

Create a project:

cvs projects create \
 --company-id 443 \
 --name "New Project" \
 --goal "Validate scope" \
 --scope "External perimeter" \
 --type-id 14 \
 --start-date 2026-05-19 \
 --estimated-hours 2 \
 --assign user@conviso.com.br \
 --assets 40641

Update a project:

cvs projects update \
--id 12345 \
--company-id 443 \
--name "Platform Pentest Q3" \
--add-tags pentest,critical \
--add-assets 100,101

Update only the project status:

cvs projects status ANALYSIS --id 12345

Delete one or more projects:

cvs projects delete \
--company-id 443 \
--ids 12345,12346 \
--force

Assets​

List assets with filters:

cvs assets list \
--company-id 443 \
--tags cloud \
--attack-surface INTERNET_FACING \
--all

Create an asset:

cvs assets create \
--company-id 443 \
--name "api-prod" \
--business-impact HIGH \
--data-classification NON_SENSITIVE \
--tags "prod,api"

Update an asset:

cvs assets update \
--id 321 \
--company-id 443 \
--name "api-prod-main" \
--business-impact HIGH \
--tags "prod,api,critical"

Delete one or more assets:

cvs assets delete \
--company-id 443 \
--ids 321,322 \
--force

Requirements​

List requirements:

cvs requirements list \
--company-id 443 \
--format table

Create a requirement:

cvs requirements create \
--company-id 443 \
--label "Req" \
--description "Desc" \
--activity "Login|Check login|REF-123"

List project requirements:

cvs requirements project \
--company-id 443 \
--project-id 26102

List requirement activities:

cvs requirements activities \
--company-id 443 \
--requirement-id 1503

Upload one or more files as evidences to a requirement activity:

cvs requirements attach \
--activity-id 123456 \
--reason "Evidence for validation"
--file ./evidence.png

List activities directly from a project:

cvs requirements activities \
--company-id 443 \
--project-id 26102

Update a requirement:

cvs requirements update \
--id 1503 \
--company-id 443 \
--label "Authentication checks" \
--description "Validate login, session, and token controls"

Delete a requirement:

cvs requirements delete \
--id 1503 \
--force

Tasks​

Create a task from a YAML file:

cvs tasks create \
--company-id 443 \
--project-id 26102 \
--label "Nuclei Scan" \
--yaml-file samples/task-nuclei.yaml

Append a task to a requirement:

cvs tasks create \
--company-id 443 \
--requirement-id 2174 \
--label "Nuclei Scan" \
--yaml-file samples/task-nuclei.yaml

Run YAML-defined tasks from project requirements:

cvs tasks run \
--company-id 443 \
--project-id 26102

List tasks for a project:

cvs tasks list \
--company-id 443 \
--project-id 26102

List only tasks with valid YAML:

cvs tasks list \
--company-id 443 \
--project-id 26102 \
--only-valid

Create a task with inline YAML:

cvs tasks create \
--company-id 443 \
--label "Quick Task" \
--yaml "name: quick\nsteps:\n - action: echo\n message: ok"

List locally approved task commands:

cvs tasks approvals list

Remove a single approved command:

cvs tasks approvals remove --hash <approval_hash>

Clear all approved task commands:

cvs tasks approvals clear

Vulnerabilities​

List vulnerabilities by severity and asset tag:

cvs vulns list \
--company-id 443 \
--severities HIGH,CRITICAL \
--asset-tags cloud \
--all

List recent vulnerabilities from the last 7 days:

cvs vulns list \
--company-id 443 \
--days-back 7 \
--severities HIGH,CRITICAL \
--all

Filter vulnerabilities by author:

cvs vulns list \
--company-id 443 \
--author "Fernando" \
--all

Run a local free-text search over the returned results:

cvs vulns list \
--company-id 443 \
--all \
--grep "jwt"

Filter vulnerabilities by local field matching:

cvs vulns list \
--company-id 443 \
--all \
--contains codeSnippet=eval( \
--contains fileName=app.py

Search DAST and Web vulnerability request and response fields:

cvs vulns list \
--company-id 443 \
--types DAST_FINDING,WEB_VULNERABILITY \
--all \
--contains request=Authorization \
--contains response=stacktrace

Show the timeline of a single vulnerability:

cvs vulns timeline --id 98765

Show vulnerability timelines aggregated from a project:

cvs vulns timeline \
--company-id 443 \
--project-id 26102 \
--last-status-change-only

Create a vulnerability:

cvs vulns create \
--type SOURCE \
--asset-id 123 \
--title "Hardcoded secret" \
--description "Secret found in source code" \
--solution "Move secret to a secure vault" \
--impact-level HIGH \
--probability-level MEDIUM \
--severity HIGH \
--file-name app.py \
--vulnerable-line 42 \
--code-snippet "API_KEY = 'secret'"

Update a vulnerability and assignees:

cvs vulns update \
--id 98765 \
--type SOURCE \
--status IN_PROGRESS \
--assignees analyst@company.com,dev@company.com

Check patch availability for SCA vulnerabilities:

cvs vulns check-sca-patches \
--company-id 443 \
--severities HIGH,CRITICAL \
--all

Batch Import Findings​

Import multiple findings (SAST, SCA, DAST, Container, IaC, Secret, API) for an asset in a single atomic operation:

Preview before import:

cvs vulns batch \
--asset-id 27516 \
--file findings.json \
--dry-run

Import findings:

cvs vulns batch \
--asset-id 27516 \
--file findings.json

Upsert mode (update existing findings if ID present, create if not):

cvs vulns batch \
--asset-id 27516 \
--file findings.json \
--upsert

Example JSON format (SAST):

[
{
"assetId": 27516,
"sast": {
"assetId": 27516,
"title": "SQL Injection",
"description": "User input concatenated into SQL query",
"severity": "CRITICAL",
"fileName": "app.py",
"vulnerableLine": 42,
"firstLine": 40,
"codeSnippet": "query = f'SELECT * FROM users WHERE id = {user_id}'",
"solution": "Use parameterized queries",
"impactLevel": "HIGH",
"probabilityLevel": "HIGH"
}
}
]

Supported finding types: SAST, SCA, DAST, Container, IaC, Secret, API

SBOM​

List SBOM components:

cvs sbom list \
--company-id 443 \
--name log4j \
--all \
--format csv \
--output sbom.csv

Import an SBOM file for an asset:

cvs sbom import \
--company-id 443 \
--file bom.cdx \
--asset-id 123

Check vulnerabilities from the OSV API using platform assets:

cvs sbom check-vulns \
--company-id 443 \
--asset-ids 123 \
--tags foo \
--format json \
--output osv.json

Check vulnerabilities from a local CycloneDX file:

cvs sbom check-vulns \
--file bom.cdx \
--format json \
--output osv.json

Security Gate​

Evaluate whether an asset's vulnerabilities comply with security policies, and fail with a non-zero exit code if thresholds are exceeded — designed to be used as a CI/CD pipeline gate.

Run the security gate using platform-configured rules:

cvs security-gate --asset-id 31894

Run the security gate using a local YAML rules file:

cvs security-gate \
--asset-id 31894 \
--company-id 443 \
--rules-file security-gate.yml

Scope the evaluation to a specific branch:

cvs security-gate \
--asset-id 31894 \
--company-id 443 \
--branch feature/my-feature

Export the full result to a JSON file:

cvs security-gate \
--asset-id 31894 \
--output gate-result.json

Example security-gate.yml rules file:

rules:
- from: any
severity:
critical:
maximum: 0
high:
maximum: 5
max_days_to_fix: 30
medium:
maximum: 10
max_days_to_fix: 60

Notes:

  • --company-id is required when --rules-file or --branch is provided.
  • --branch requires an exact, case-sensitive match. If the branch is not found, the command exits with an error listing the available branches for the asset.
  • Vulnerabilities without a branch association (legacy issues) are excluded from the evaluation when --branch is used.
  • Exit code 0 means the gate passed; exit code 1 means either the gate failed (thresholds exceeded) or a technical error occurred (network, authentication, invalid input) — the error message always distinguishes the two cases.

Bulk Operations​

Assets CSV​

Create assets from CSV:

cvs bulk assets \
--company-id 443 \
--file assets.csv \
--op create

Preview an update without applying it:

cvs bulk assets \
--company-id 443 \
--file assets.csv \
--op update \
--preview-only

Show the bulk assets template:

cvs bulk assets --show-template

Repository sample:

  • samples/assets_sample.csv

Requirements CSV​

Create requirements from CSV:

cvs bulk requirements \
--company-id 443 \
--file reqs.csv \
--op create

Show the bulk requirements template:

cvs bulk requirements --show-template

Repository sample:

  • samples/requirements_sample.csv

Vulnerabilities CSV or SARIF​

Create vulnerabilities from CSV:

cvs bulk vulns \
--company-id 443 \
--file vulns.csv \
--op create

Create vulnerabilities from SARIF:

cvs bulk vulns \
--company-id 443 \
--file vulns.sarif \
--op create \
--sarif

Show the bulk vulnerabilities template:

cvs bulk vulns --show-template

Repository samples:

  • samples/vulns_sample.csv
  • vulns.sarif

Access Control​

Update the access profile of a user:

cvs accesscontrol user-profile \
--company-id 443 \
--user-id 123 \
--profile-id 7

Update the teams associated with a user:

cvs accesscontrol user-teams \
--company-id 443 \
--user-id 123 \
--team-ids 10,11

Remove all teams from a user:

cvs accesscontrol user-teams \
--company-id 443 \
--user-id 123 \
--clear

Bulk update user access from CSV:

cvs accesscontrol bulk-users --file users.csv

The access control bulk template uses the following columns:

  • company_id
  • user_id
  • profile_id
  • team_ids
  • clear_teams

Authentication Commands​

Login​

Save API key securely to ~/.config/cvs/credentials:

cvs auth login

You will be prompted to enter your API key. The CLI will show you where to get it:

📚 Where to get your API key:
1. Go to: https://app.convisoappsec.com/spa/company/[COMPANY_ID]/api-keys
2. Click 'Generate New Key'
3. Copy the key and paste it below

Check Login Status​

cvs auth whoami

Example output:

✅ You are logged in
â„šī¸ API Key: LwYrO_7AT3...Pcps
â„šī¸ Credentials location: /Users/you/.config/cvs/credentials

Logout​

Remove stored credentials:

cvs auth logout

CI/CD Behavior Notes​

  • GraphQL/API errors return exit code 1.
  • security-gate follows the same convention: exit code 1 on gate failure or on any technical error.
  • --quiet silences informational logs.
  • --verbose shows detailed request flow on paginated operations.
  • The CLI checks for updates at startup.
    • Disable check with CONVISO_CLI_SKIP_UPDATE_CHECK=1.
    • Override remote version with CONVISO_CLI_REMOTE_VERSION when needed.

Help and Discovery​

Use built-in help at any level:

cvs --help
cvs projects --help
cvs vulns list --help
cvs auth login --help

Or use the shorter alias:

cvs vulns list --help
cvs auth whoami

Reference​

This documentation was updated based on the current README.md in the official repository:

Contribute to the Docs

Found something outdated or missing? Help us improve the documentation with a quick suggestion or edit.

How to contribute

Resources

By exploring our content, you'll find resources that will enhance your understanding of the importance of a Security Application Program.

Conviso Blog: Explore our blog, which offers a collection of articles and posts covering a wide range of AppSec topics. The content on the blog is primarily in English.

Conviso's YouTube Channel: Access a wealth of informative videos covering various topics related to AppSec. Please note that the content is primarily in Portuguese.