Oxid is a Rust-native security scanner aggregator with two halves living side by side in this repo:
| Folder | What it is | Stack |
|---|---|---|
cli/ |
The scan engine. Aggregates cargo-audit, clippy, cargo-sbom, cargo-deny, cargo-geiger and emits a unified report (human / JSON / SARIF). |
Rust |
web/ |
A minimalist dashboard that connects to GitLab, imports Rust projects, runs oxid scan on demand, and visualizes findings. |
Next.js 14, Prisma, SQLite |
The CLI is the engine. The web app shells out to it — never reimplements scan logic. See cli/README.md and web/README.md for the per-half details.
cd cli
cargo build --release
./target/release/oxid scanOr install onto PATH:
cd cli
cargo install --path .
oxid scan --format jsonThe web app needs the CLI binary reachable. Either install with cargo install --path cli so oxid is on PATH, or set OXID_BIN to its absolute path in web/.env.local.
cd web
npm install
cp .env.example .env.local
# Set GITLAB_APP_ID, GITLAB_APP_SECRET, OXID_BIN
npx prisma db push
npm run devOpen http://localhost:3000, click Connect GitLab, import a Rust repo, scan it.
oxid/
├── cli/ # Rust CLI (the scan engine)
│ ├── src/
│ ├── tests/
│ ├── Cargo.toml
│ └── README.md
├── web/ # Next.js web dashboard
│ ├── src/
│ ├── prisma/
│ ├── package.json
│ └── README.md
├── README.md # this file
├── AGENTS.md # project-wide rules for AI assistants
└── .gitignore
The web app does not import the CLI as a library. It treats oxid as a black-box subprocess:
- User clicks Scan now in the web UI.
- The orchestrator at
web/src/lib/scanner.tsclones the GitLab repo into a temp directory. - It spawns
oxid scan --format jsonwithcwd: <tempDir>(the CLI scans the current working directory; there is no--pathflag). - Stdout is parsed as
Finding[]— the same struct defined incli/src/finding.rs. The TypeScript mirror lives atweb/src/lib/types.ts. - Findings + a severity summary are written to SQLite. The temp dir is always removed in a
finallyblock (it contains an OAuth-tokened.git/config).
The single contract between the two halves is the JSON shape of Finding. If you change the Rust struct in cli/src/finding.rs, mirror the change in web/src/lib/types.ts.
See cli/ for license details.