Skip to content

Commit 91aa365

Browse files
Merge pull request #1 from AtLongLastAnalytics/release/1.1.0
Release v1.1.0 — batch scanning, dashboard, multi-format output
2 parents ce1e48e + f47b1dc commit 91aa365

31 files changed

Lines changed: 3763 additions & 601 deletions

.env.example

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# =============================================================================
2+
# Copyright (c) AtLongLast Analytics LLC
3+
4+
# Licensed under the Apache License, Version 2.0
5+
6+
# Project: https://github.com/AtLongLastAnalytics/visar
7+
# Author: Robert Long
8+
# Date: 2026-03
9+
# Version: 1.1.0
10+
11+
# File: .env.example
12+
# Description: Template for environment variables. Copy this file to .env and
13+
# replace the placeholder with your token. Never commit .env to version
14+
# control — it is excluded by .gitignore.
15+
# =============================================================================
16+
17+
# Generate a classic GitHub personal access token at:
18+
# Settings > Developer Settings > Personal access tokens > Tokens (classic)
19+
# Required scope: public_repo
20+
21+
VISAR_AUTH_TOKEN = "<your-github-personal-access-token>"

.gitgnore

Lines changed: 0 additions & 25 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# =============================================================================
2+
# Copyright (c) AtLongLast Analytics LLC
3+
4+
# Licensed under the Apache License, Version 2.0
5+
6+
# Project: https://github.com/AtLongLastAnalytics/visar
7+
# Author: Robert Long
8+
# Date: 2026-03
9+
# Version: 1.1.0
10+
11+
# File: .github/workflows/ci.yml
12+
# Description: Continuous integration pipeline. Runs on every push and pull
13+
# request to main, and can be triggered manually via workflow_dispatch.
14+
# Steps: checkout → install deps (uv) → lint → format check → unit tests.
15+
# =============================================================================
16+
17+
name: CI
18+
19+
on:
20+
push:
21+
branches: [main]
22+
pull_request:
23+
branches: [main]
24+
workflow_dispatch: # allow manual runs from the GitHub Actions UI
25+
26+
permissions:
27+
contents: read # minimum permissions — read-only access to repo contents
28+
29+
jobs:
30+
test:
31+
name: Test
32+
runs-on: ubuntu-latest
33+
34+
steps:
35+
- name: Checkout repository
36+
uses: actions/checkout@v4
37+
38+
- name: Set up uv
39+
# installs uv and the specified Python version
40+
uses: astral-sh/setup-uv@v5
41+
with:
42+
python-version: "3.12"
43+
44+
- name: Install dependencies
45+
# --frozen ensures uv.lock is respected and not updated during CI
46+
run: uv sync --frozen
47+
48+
- name: Lint with ruff
49+
run: uv run ruff check .
50+
51+
- name: Check formatting with ruff
52+
run: uv run ruff format --check .
53+
54+
- name: Run tests
55+
env:
56+
VISAR_AUTH_TOKEN: ${{ secrets.VISAR_AUTH_TOKEN }}
57+
run: uv run python -m unittest discover -s tests -v

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# =============================================================================
2+
# Copyright (c) AtLongLast Analytics LLC
3+
4+
# Licensed under the Apache License, Version 2.0
5+
6+
# Project: https://github.com/AtLongLastAnalytics/visar
7+
# Author: Robert Long
8+
# Date: 2026-03
9+
# Version: 1.1.0
10+
11+
# File: .gitignore
12+
# Description: This file specifies files/folders that Git should not track.
13+
# This includes the virtual environment directories (.venv) and environment
14+
# variable file (.env).
15+
# =============================================================================
16+
17+
# Exclude environment variable file
18+
.env
19+
20+
# User-defined repo list — copy repos.txt.example to repos.txt and add your own
21+
repos.txt
22+
23+
# Local Claude Code memory (never commit)
24+
.claude/
25+
26+
# Exclude the virtual environment folder
27+
.venv/
28+
29+
# Ignore Python bytecode and cache directories
30+
__pycache__/
31+
*.py[cod]
32+
33+
# Scan outputs and generated dashboard — rebuilt locally, not committed
34+
data/*
35+
!data/example-*
36+
37+
# Local run logs — keep only example logs in version control
38+
logs/visar_*.log
39+
40+
# Local development tracking (not for repo)
41+
CHANGELOG.md
42+
43+
# Note: uv.lock should be committed — it pins exact dependency versions

README.md

Lines changed: 120 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,133 @@
22

33
<img src="docs/visar-logo.png" alt="VISaR logo" width="150" style="margin-top:50px"></img>
44

5-
# Welcome to VISaR 👋
5+
# Welcome to VISaR
6+
[![CI](https://github.com/AtLongLastAnalytics/visar/actions/workflows/ci.yml/badge.svg)](https://github.com/AtLongLastAnalytics/visar/actions/workflows/ci.yml)
7+
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE.txt)
8+
[![Python 3.12+](https://img.shields.io/badge/Python-3.12%2B-blue.svg)](https://www.python.org/)
69

7-
**Automate vulnerability scanning and reporting using open-source components.**
10+
**Free, open-source vulnerability scanning and reporting for GitHub repositories.**
811

912
## What is VISaR?
1013

11-
VISaR (Vulnerability Identification, Scanning and Reporting) is an open-source tool designed to automatically scan code repositories for vulnerabilities. VISaR generates detailed CSV reports summarizing potential issues: an ideal solution for engineers and developers to make informed decisions regarding ensure code safety.
14+
VISaR (Vulnerability Identification, Scanning and Reporting) is a free, open-source Python tool that automatically scans GitHub repositories for known vulnerabilities and generates detailed, actionable reports. Output is available in CSV, JSON, or as a self-contained interactive HTML dashboard, . pojyymaking it easy to review, share, and act on findings.
1215

13-
With usability in mind, VISaR is written in Python and uses
14-
best-in-class open-source components; the [OSSF scorecard](https://github.com/ossf/scorecard) for vulnerability identification and the [OSV Database](https://osv.dev/) for vulnerability information.
16+
VISaR uses best-in-class open-source components: the [OSSF Scorecard](https://github.com/ossf/scorecard) for vulnerability identification and the [OSV Database](https://osv.dev/) for vulnerability enrichment (severity, description, and aliases).
1517

1618
**Who is VISaR for?**
1719

18-
- **Data Engineers:** Quickly evaluate code before integrating it into your data platform.
19-
- **Software Engineers:** Assess your own code for vulnerabilities before it reaches production systems.
20-
- **Independent Developers and Hobbyists:** Verify code generated by AI assistants or community contributions.
20+
- **Data Engineers:** Evaluate open-source libraries and frameworks before integrating them into your data platform.
21+
- **Software Engineers:** Assess your codebase for known vulnerabilities before a release or production deployment.
22+
- **Independent Developers and Hobbyists:** Verify code generated by AI assistants or sourced from the community.
2123

2224

2325
## 1. Using VISaR
2426

2527
**Pre-requisites**
2628

27-
To use VISaR, ensure you have the following:
29+
To use VISaR, ensure you have the following installed and configured:
2830

29-
- Python 3.8+ (the code was developed in Python 3.12)
30-
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
31-
- The most recent OSSF scorecard Docker image ([follow instructions here](https://github.com/ossf/scorecard?tab=readme-ov-file#installation))
32-
- A classic Github auth token _(settings > Developer Settings > Personal access tokens > Tokens (classic))_ and set the scope to public_repo. This needs to be included in the `.env` file.
31+
- [uv](https://docs.astral.sh/uv/) — Python package and environment manager. uv will automatically download Python 3.12+ if needed.
32+
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) — required to run the OSSF Scorecard container.
33+
- The OSSF Scorecard Docker image, pulled locally:
34+
35+
```
36+
docker pull gcr.io/openssf/scorecard:stable
37+
```
38+
39+
- A classic GitHub personal access token _(Settings > Developer Settings > Personal access tokens > Tokens (classic))_ with the `public_repo` scope. This is stored in a `.env` file at the project root (never committed to version control).
40+
41+
**System Requirements**
42+
43+
- Python 3.12+ (managed automatically by uv)
44+
- Docker Desktop with at least 2 GB of available memory
45+
- Network access to the GitHub API (`api.github.com`) and the OSV API (`api.osv.dev`)
46+
- Approximately 1 GB of free disk space for the OSSF Scorecard Docker image
47+
48+
**Install uv** (skip if already installed):
49+
50+
**Windows (PowerShell):**
51+
```
52+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
53+
```
54+
55+
**Mac / Linux:**
56+
```
57+
curl -LsSf https://astral.sh/uv/install.sh | sh
58+
```
3359
3460
**Step-by-Step Instructions**
3561
36-
These instructions are for Windows users only.
37-
1. Clone this repository
62+
1. Clone this repository.
3863
39-
2. Create a _.env_ file in the root directory and populate with:
64+
2. Create a `.env` file in the root directory and add your GitHub token:
4065
4166
```
42-
GITHUB_AUTH_TOKEN = "<github-auth-token>"
67+
GITHUB_AUTH_TOKEN = "<your-github-personal-access-token>"
4368
```
44-
45-
3. Run the _setup_ PowerShell script from the root directory to create a virtual environment, install dependencies, and activate it:
4669
47-
```
48-
./scripts/setup.ps1
49-
```
70+
A `.env.example` template is included at the project root for reference.
71+
72+
3. From the root directory, install dependencies. This creates `.venv` and installs everything from `pyproject.toml` in one step:
5073
51-
4. From the root directory, run the test suite using:
74+
```
75+
uv sync
76+
```
77+
78+
4. From the root directory, run the test suite to verify everything is working:
5279
53-
```
54-
python -m unittest discover -s tests
5580
```
81+
uv run python -m unittest discover -s tests
82+
```
83+
84+
All tests should pass. If any fail, check the error message and ensure Docker Desktop is running and the OSSF Scorecard image has been pulled.
5685
57-
You should see that all tests have passed. If not, the error message should guide you to the problem.
58-
59-
5. Now you are ready to run the pipeline. From the root directory, move into the src folder, and run the application:
60-
86+
5. Move into the `src/` folder and run the application:
87+
88+
**Single repository scan (default CSV output):**
6189
```
6290
cd src/
63-
python main.py <full-github-repo>
91+
uv run python main.py <full-github-repo-url>
92+
```
93+
94+
**Single repository scan with JSON output:**
95+
```
96+
uv run python main.py <full-github-repo-url> --output-format json
97+
```
98+
99+
**Batch scan — scan multiple repositories from a text file:**
100+
```
101+
uv run python main.py --batch ../repos.txt
102+
uv run python main.py --batch ../repos.txt --output-format json
103+
```
104+
105+
The batch file should contain one GitHub repository URL per line. Lines starting with `#` and blank lines are ignored. A `repos.txt.example` file is provided as a template — copy it to `repos.txt` and replace the contents with your own repos (`repos.txt` is gitignored).
106+
107+
**Generate an HTML dashboard from all scan outputs in a directory:**
108+
```
109+
uv run python dashboard.py
64110
```
65111
112+
Or point to a specific data directory:
113+
```
114+
uv run python dashboard.py <path-to-data-dir>
115+
```
116+
117+
The dashboard is an ad-hoc step — run scans as many times as needed first, then generate the HTML report when you are ready to review. A single self-contained `dashboard.html` is written to the `data/` directory, embedding all scan datasets. Use the dropdown to switch between scans, the date filter to narrow by scan date, and the severity pills to focus on the most critical findings. Rows can be expanded to read the full vulnerability detail.
118+
119+
**CLI Reference**
120+
121+
| Argument | Type | Default | Description |
122+
|---|---|---|---|
123+
| `repo_url` | positional | — | Full GitHub repository URL. Required unless `--batch` is used. |
124+
| `--batch FILE` | optional | — | Path to a text file containing one URL per line. Use instead of `repo_url`. |
125+
| `--output-format FORMAT` | optional | `csv` | Output format: `csv` or `json`. |
126+
| `-h` / `--help` | flag | — | Display help message and exit. |
127+
128+
**Exit codes:** `0` — completed successfully (including when no vulnerabilities are found). `1` — scan failed; see the `logs/` directory for details.
129+
66130
<br>
67-
The CSV file generated by a successful run is ready to consume in a tool like Microsoft Excel, see Figure 1. The key columns for decision making are the Severity and Details which together describe a given vulnerability.
131+
The output file generated by a successful run is placed in the `data/` directory. The default CSV format is ready to open in Microsoft Excel or any spreadsheet tool — see Figure 1. The key columns for decision-making are **Severity** and **Details**, which together describe each finding.
68132
69133
<br>
70134
<br>
@@ -77,21 +141,21 @@ The CSV file generated by a successful run is ready to consume in a tool like Mi
77141
<p><strong>Figure 1:</strong> Example VISaR Output</p>
78142
</div>
79143
80-
Example logs for a successful run and a failed run are provided in the [logs directory](./logs/).
144+
Example logs for a successful run and a failed run are provided in the [logs directory](./logs/). Example scan output files (CSV and JSON) are provided in the [data directory](./data/); these show the format a real scan produces and can be used to generate a dashboard without running a full scan.
81145
82146
## 2. Technical Overview
83-
The user provides a GitHub code repository URL to VISaR which then automatically performs a code scan, sends requests to the OSV API and enriches the data before writing vulnerability information to a CSV file.
147+
The user provides a GitHub repository URL to VISaR, which automatically performs a vulnerability scan, queries the OSV API to enrich findings, and writes a structured report in the chosen format.
84148
85149
**How VISaR works:**
86150
87-
The workflow below aligns with the architecture diagram shown Figure 2.
151+
The workflow below aligns with the architecture diagram shown in Figure 2.
88152
89153
1. OSSF Scorecard scans the repository and generates a summary file.
90-
2. A second OSSF Scorecard scan generates a file of known vulnerabilties (saved temporarily).
91-
3. A list of vulnerability IDs are harvested from the temporary data file.
92-
4. Vulnerability IDs are sent to the OSV API with severity and summary description requested.
93-
5. Key vulnerability information is extracted from the JSON payload.
94-
6. The vulnerability IDs, severity, and plain-text summary are compiled into a structured CSV file.
154+
2. A second OSSF Scorecard scan generates a file of known vulnerabilities (saved temporarily).
155+
3. A list of vulnerability IDs is extracted from the temporary file.
156+
4. Vulnerability IDs are sent to the OSV API to retrieve severity ratings and plain-text descriptions.
157+
5. Key vulnerability information is extracted from the API response.
158+
6. The vulnerability IDs, severity, and descriptions are compiled into a structured report (CSV or JSON, depending on the `--output-format` flag).
95159
96160
<br>
97161
@@ -103,31 +167,35 @@ The workflow below aligns with the architecture diagram shown Figure 2.
103167
<p><strong>Figure 2:</strong> VISaR Architecture Diagram</p>
104168
</div>
105169
106-
107-
**Overview of the Project Structure**
108170
109-
The VISaR codebase follows a typical src structure.
171+
**Overview of the Project Structure**
172+
173+
The VISaR codebase follows a standard `src/` layout.
174+
175+
- The application code is in `src/`. `main.py` is the scan entry point and `dashboard.py` is the HTML report entry point.
176+
177+
- The `helpers/` package is a collection of modules, each containing a logical grouping of functions used in the main pipeline. `dashboard_funcs.py` handles all HTML generation and is intentionally separate from the scan pipeline.
110178
111-
- The application code is stored in the `src/` directory, with `main.py` being the entry point.
179+
- Each module in `helpers/` has an associated test file in `tests/`. Within each test script, all tests for a given function are grouped into their own class. We aim for close to 100% test coverage.
112180
113-
- The `helpers/` package is a collection of modules, each containing a logical grouping of functions used in the main application.
181+
- Run details are captured in a `.log` file in the `logs/` directory. If a run fails, this is the first place to look.
114182
115-
- Each module within the `helpers` package has an associated test file in the `tests/` directory. Within each test script, all of the tests for a given function are grouped into their own class. We aim to have close to 100% test coverage!
183+
- The `data/` directory contains scan output files, named by date and repository (e.g. `20260320-owner-repo_vulnids.csv`). The suffix depends on the chosen format: `_vulnids.csv` (default) or `_vulnids.json`. Running `dashboard.py` writes a single `dashboard.html` to this directory, embedding all scan datasets.
116184
117-
- Run details are captured in a `.log` file found within the `logs/` directory. If a run fails, this is where you should start troubleshooting.
185+
- Project dependencies are declared in `pyproject.toml` at the root. Running `uv sync` creates `.venv` and installs everything. The `scripts/` directory contains `setup.ps1` (Windows) and `setup.sh` (Mac/Linux) as convenience wrappers around `uv sync`.
118186
119-
- The `data/` directory is where you can find the output of completed runs. The files ending with `_vulnids.csv` are the main output containing the vulnerability information.
120187
121-
- A PowerShell script, `setup.ps1`, is provided in the `scripts/` directory. This script should be ran the first time using VISaR, it creates the virtual environment and installs all dependencies for you.
188+
## 3. Roadmap
122189
190+
See [docs/ROADMAP.md](./docs/ROADMAP.md) for planned features and future direction.
123191
124-
## 3. Contribute
125-
Thank you for wanting to contribute and improve VISaR! We welcome contributions from the community and are grateful for your support.
192+
## 4. Contribute
193+
Thank you for wanting to contribute to VISaR! We welcome contributions from the community.
126194
127-
Before contributing, please read our guidelines which describe our code style and testing approach: [/docs/Contributing.md](./docs/Contributing.md).
195+
Before contributing, please read our guidelines covering code style, linting, and testing: [docs/Contributing.md](./docs/Contributing.md).
128196
129197
By contributing to this project, you agree that your contributions will be licensed under the [Apache-2.0 License](LICENSE.txt).
130198
131-
## 4. License
199+
## 5. License
132200
133201
VISaR is completely free, open-source, and licensed under the [Apache-2.0 License](LICENSE.txt).

0 commit comments

Comments
 (0)