CV Scanner - User Guide
Overview
CV Scanner (cvscan) is a security scanning tool built by Cloudvisor to help teams identify leaked secrets and Infrastructure-as-Code (IaC) misconfigurations in their source code repositories — before they become incidents.
The tool is designed to support the implementation of SEC02-BP03 - Store and use secrets securely by surfacing hardcoded credentials, API keys, tokens, and weak IaC configurations that could expose your AWS environment.
Key use cases
- Pre-engagement security review: Scan all repositories before a Well-Architected Review to identify and remediate secrets exposure.
- Repository hygiene: Detect credentials that were accidentally committed to git history and have since been removed from the working tree but remain in historical commits.
- IaC audit: Identify Terraform and CloudFormation configurations that deviate from security best practices.
- Compliance preparation: Generate a structured report of findings to support evidence gathering for regulatory or internal audits.
Privacy & Security
Understanding what
cvscanaccesses and what it transmits is important before running it against any repository. This section explains the tool’s data handling in full.
What the tool accesses
cvscan reads the following data from the target directory or repository:
- File system contents — all files under the specified path are read and scanned for secret patterns and IaC misconfigurations.
- Git history — all commits in the repository’s git log are scanned, including file diffs. This allows detection of secrets that were committed and later deleted.
- Commit metadata — author names, commit hashes (truncated to 8 characters), and commit dates are used to annotate findings.
What is NOT collected or stored
- Actual secret values are never stored in plain text. All secrets detected during scanning are immediately redacted using a masking algorithm that retains only the first four and last four characters (e.g.,
AKIA****4K2A). Secrets of eight characters or fewer are fully masked (********). - Source code files are not transmitted. When findings are submitted to Cloudvisor, only structured metadata is sent — not file contents, diffs, or raw code.
- No persistent credential storage. The tool does not write API keys, tokens, or credentials to disk. Submission credentials are passed as CLI flags and exist only in memory during execution.
How user data is handled
By default, cvscan runs entirely locally — no network calls are made and no data leaves your machine. Findings are written to two local files:
cvscan-report.html— a human-readable HTML report.cvscan-results.json— a machine-readable JSON file for optional later submission
Submission to the Cloudvisor backend is strictly opt-in and is only triggered when the --id and --token flags are provided. When submission is performed, the following data is sent:
| Field | Description |
|---|---|
| Engagement ID | The eng_xxx identifier provided by Cloudvisor |
| Scan timestamp | UTC timestamp of when the scan was run |
| Repository path | The local path string passed to cvscan (not contents) |
| Summary counts | Total findings, secrets count, IaC count, repos scanned |
| Finding metadata | Rule ID, description, severity, file path, line numbers |
| Redacted secret | Masked secret value (never the actual value) |
| Commit metadata | 8-character commit SHA, author name, commit date |
| IaC details | Resource identifier, provider, service, recommended resolution |
Assumptions and limitations
- The tool assumes that the local repository was cloned or checked out by a trusted operator before scanning.
- Scanning a repository does not modify any files. The tool is entirely read-only with respect to the target directory.
- Submission uses HTTPS and authenticates via a short-lived bearer token provided by Cloudvisor.
Explicit reassurance
cvscan was built with the assumption that the repositories it scans may contain sensitive business logic and confidential data. The tool was designed with a minimum necessary data principle: it collects and transmits only what is required to produce a meaningful security finding report, and nothing more.
If you have concerns about running cvscan against specific repositories, you can use the --scanners flag to limit the scan scope, or run locally without submission and review the HTML report before sharing any results.
Features
Secrets scanning
Powered by gitleaks, the secrets scanner detects leaked credentials, API keys, and tokens across:
- The current working tree (uncommitted and committed files)
- The full git commit history (including deleted content)
The scanner matches against hundreds of built-in rules covering common providers including AWS, GitHub, Slack, Stripe, Twilio, Azure, GCP, and many others.
IaC misconfiguration scanning
Powered by trivy, the IaC scanner detects security misconfigurations in:
- Terraform configurations (
.tffiles) - CloudFormation templates (
.yaml,.json,.templatefiles)
Findings include the affected resource, the misconfiguration description, the severity level, and a recommended remediation.
HTML report
After each scan, an HTML report is automatically generated and opened in the default browser. The report presents findings grouped by type (Secrets / IaC), with severity badges, affected file paths, and line numbers.
JSON sidecar
A machine-readable .cvscan-results.json file is written alongside the HTML report. This file can be used for programmatic processing or submitted to Cloudvisor at a later time using the cvscan submit command.
Interactive terminal UI
Running cvscan without arguments launches an interactive terminal UI (TUI) that guides you step-by-step through scanner selection, repository path input, and optional submission.
Optional findings submission
Findings can be submitted to the Cloudvisor backend for review as part of a Well-Architected engagement. Submission is opt-in and requires credentials provided by your Cloudvisor engagement team.
Installation
Prerequisites
- macOS, Linux, or Windows
- Git installed and available on the
PATH(required for secrets scanning of git history) - No additional runtime dependencies —
cvscanis a self-contained binary
Homebrew (recommended)
View code
brew tap devisory-engineering/cvscan && brew install cvscanDirect download
Download the latest release for your platform from the GitHub Releases page. Extract the archive and place the cvscan binary somewhere on your PATH.
macOS Gatekeeper note: On macOS, binaries downloaded from the internet trigger a quarantine warning. After extracting the archive, run the following command to clear the quarantine flag before executing:
View code
xattr -cr cvscan
Build from source
Requires Go 1.21 or later.
View code
git clone https://github.com/devisory-engineering/cvscan.git
cd cvscan
go build -o cvscan ./cmd/cvscan/Verify installation
View code
cvscan --versionUsage
Quick start
Provide the path to a directory containing one or more repositories, or to a single repository directly:
View code
# Scan a folder containing multiple repositories
cvscan /path/to/repos
# Scan a single repository
cvscan /path/to/my-appThe tool automatically determines whether the path is a single git repository (contains .git/) or a parent directory of multiple repositories. The HTML report is generated and opened in your browser automatically.
Scanner selection
By default, both the secrets scanner and the IaC scanner are enabled. To run only one:
View code
# Secrets only
cvscan --scanners secrets /path/to/repos
# IaC only
cvscan --scanners iac /path/to/repos
# Both (default — equivalent to omitting the flag)
cvscan --scanners secrets,iac /path/to/reposCustom report output path
View code
cvscan -o /tmp/my-report.html /path/to/reposThe JSON sidecar (.cvscan-results.json) is always written to the same directory as the HTML report.
Interactive mode
View code
cvscanLaunches the interactive terminal UI. Use arrow keys to navigate scanner options, type a path when prompted, and follow the on-screen instructions.
Scan and submit to Cloudvisor
To scan and immediately submit findings as part of a Well-Architected engagement:
View code
cvscan --id eng_7kx9m2p4q8 --token tok_a3f8x9k2m1 /path/to/reposBoth --id and --token are required for submission. These credentials are provided by your Cloudvisor engagement team.
Submit previously generated results
If you ran a scan locally and want to submit the results at a later time:
View code
# Submit from the default sidecar file in the current directory
cvscan submit --id eng_7kx9m2p4q8 --token tok_a3f8x9k2m1
# Submit from a specific file
cvscan submit --id eng_7kx9m2p4q8 --token tok_a3f8x9k2m1 --file /path/to/.cvscan-results.jsonAll flags
| Flag | Short | Default | Description |
|---|---|---|---|
--id | Engagement ID (eng_xxx), required for submission | ||
--token | Submission token (tok_xxx), required with --id | ||
--scanners | secrets,iac | Comma-separated list of scanners to run | |
--output | -o | cvscan-report.html | Path for the HTML report output |
Report Explanation
Report structure
The HTML report is divided into two main sections:
- Secrets findings — credentials, tokens, and API keys detected in source code or git history
- IaC findings — Terraform and CloudFormation misconfigurations
Each section displays a count badge at the top and lists all findings in a table.
Secrets finding fields
| Field | Description |
|---|---|
| Rule | The rule ID that triggered the match (e.g., aws-access-token, github-pat) |
| Description | Human-readable description of the secret type |
| Severity | Always HIGH for secrets findings |
| Repository | Name of the repository where the finding was detected |
| File | Path to the file containing the finding, relative to the repository root |
| Lines | Start and end line numbers of the matched content |
| Secret (redacted) | Masked version of the detected secret value |
| Commit | 8-character git commit SHA, or uncommitted for working-tree findings |
| Author | Git commit author name |
| Date | Git commit date |
IaC finding fields
| Field | Description |
|---|---|
| Rule | The Trivy check ID that triggered the match |
| Description | Description of the misconfiguration |
| Severity | CRITICAL, HIGH, MEDIUM, or LOW |
| Repository | Name of the repository where the finding was detected |
| File | Path to the affected configuration file |
| Lines | Affected line range in the file |
| Resource | The logical resource identifier within the IaC template |
| Provider | Cloud provider (e.g., aws) |
| Service | AWS service category (e.g., s3, iam) |
| Resolution | Recommended remediation step |
Interpreting results
CRITICALandHIGHfindings should be treated as immediate action items. For secrets, this means revoking and rotating the exposed credential. For IaC, this means updating the configuration before deploying.MEDIUMandLOWfindings represent security improvements that reduce risk but may be addressed in a planned remediation cycle.uncommittedsecrets were found in the working tree (files that exist on disk but have not been committed). These are typically easier to remediate — update the file, ensure the value is moved to a secrets manager, and confirm the secret has not been pushed to any remote.- Historical commit secrets (showing a commit SHA) may require credential rotation even if the file has since been deleted, as the secret remains accessible in git history to anyone with repository access.
Example output summary
View code
Total: 12 findings (4 secrets, 8 IaC) across 3 repos
secrets / api-service ... 2 findings
secrets / infra ... 2 findings
iac / infra ... 8 findings
Results saved: .cvscan-results.json
Report saved: cvscan-report.htmlConfiguration
Limiting scanners
Use --scanners to run only the scanner types relevant to your review:
View code
# Secrets only
cvscan --scanners secrets /path/to/repos
# IaC only
cvscan --scanners iac /path/to/reposSuppressing known findings (gitleaks ignore)
If a finding is a known false positive (e.g., a test fixture, an example value in documentation), create a .gitleaksignore file in the repository root and add the finding’s fingerprint:
View code
# .gitleaksignore
# Suppress example API key in README
abc123def456...7890:README.md:aws-access-token:12Fingerprints are shown in the HTML report and in the JSON sidecar.
Custom gitleaks rules
Advanced users can supply a custom gitleaks configuration file using the GITLEAKS_CONFIG environment variable or by placing a .gitleaks.toml file in the repository root. Refer to the gitleaks documentation for the configuration schema.
Custom report path
View code
cvscan -o /tmp/reports/scan-$(date +%Y%m%d).html /path/to/reposLimitations
- Requires local repository access.
cvscancannot scan remote repositories directly. Repositories must be cloned to the local file system before scanning. - Git history requires a full clone. Shallow clones (
git clone --depth 1) will not expose historical commits. For a complete secrets scan, clone with full history. - IaC scanning covers Terraform and CloudFormation only. Other IaC formats (CDK, Pulumi, Ansible, Helm) are not currently supported.
- No remediation automation. The tool identifies and reports findings but does not automatically fix or rotate credentials. Remediation must be performed manually.
- False positives are possible. Pattern-based secrets detection can produce false positives for high-entropy strings that are not actual credentials. Review all findings before acting on them.
- Scan performance scales with repository size. Very large repositories with deep git histories may take several minutes to scan.
Troubleshooting
macOS: “cvscan” cannot be opened because the developer cannot be verified
macOS Gatekeeper blocks unsigned binaries downloaded from the internet. Run the following command on the extracted binary, then try again:
View code
xattr -cr cvscanNo repositories found
View code
error: no repositories found in /path/to/dirThis error means the specified path either does not exist or contains no subdirectories with a .git folder. Verify:
- The path exists and is accessible:
ls /path/to/dir - The target directories are valid git repositories:
ls /path/to/dir/my-repo/.git - If scanning a single repository, point directly to its root:
cvscan /path/to/dir/my-repo
Submission fails with “findings already submitted for this ID”
Each engagement ID can only receive one submission. If you need to resubmit corrected results, contact your Cloudvisor engagement team to have the previous submission cleared.
Submission fails with “invalid engagement ID”
The --id value must start with eng_. Verify that you are using the correct value provided by your Cloudvisor engagement team.
View code
# Correct
cvscan --id eng_7kx9m2p4q8 --token tok_a3f8x9k2m1 /path/to/repos
# Incorrect — token passed to --id
cvscan --id tok_a3f8x9k2m1 /path/to/reposIaC scanner produces no findings
If the IaC scanner reports zero findings for a repository containing Terraform or CloudFormation files, verify that:
- Terraform files use the
.tfextension - CloudFormation templates use
.yaml,.yml,.json, or.templateextensions - The files are syntactically valid (parse errors may cause Trivy to skip them silently)
Scanner errors appear in output
Individual scanner errors (e.g., secrets / my-repo ... error) are logged to stderr and do not stop the overall scan. Remaining repositories continue to be scanned. Review stderr output for details and verify that the affected repository is a valid, accessible git repository.
Tools used
gitleaks
An open-source tool for detecting hardcoded secrets in git repositories. cvscan uses gitleaks as its secrets scanning engine, applying a comprehensive rule set of hundreds of patterns covering credentials from major cloud providers, SaaS platforms, and authentication services.
trivy
An open-source security scanner by Aqua Security. cvscan uses trivy's IaC scanning capabilities to detect misconfigurations in Terraform and CloudFormation templates, covering security best practices across compute, storage, networking, and identity services.
Benefits of using CV Scanner
- Proactive exposure detection: Surface leaked credentials before they are exploited, often catching secrets that have been in git history for months or years
- Broad coverage: A single tool covers both secrets and IaC misconfigurations across all repositories in a project
- Privacy by design: Scans run locally by default; no data leaves the machine without explicit opt-in
- Redaction-first: Actual secret values are never stored or transmitted — only masked representations
- Actionable output: Each finding includes file path, line number, and (for IaC) a recommended resolution, enabling direct remediation
- Engagement integration: Optional submission to Cloudvisor provides your engagement team with structured findings data to incorporate into the Well-Architected Review