Skip to content

Commit 192f7a6

Browse files
committed
feat: mvp-foundation architecture, ai providers, and secrets engine
1 parent e41a713 commit 192f7a6

20 files changed

Lines changed: 1630 additions & 149 deletions

File tree

.env.example

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,43 @@ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/zenvra
44
# ─── Cache / Queue ────────────────────────────────────────────────────────────
55
REDIS_URL=redis://localhost:6379
66

7-
# ─── AI (Anthropic) ───────────────────────────────────────────────────────────
8-
# Get yours at: https://console.anthropic.com
9-
ANTHROPIC_API_KEY=sk-ant-...
7+
# ─── AI Provider ──────────────────────────────────────────────────────────────
8+
# Zenvra supports multiple AI providers for explanations and fix generation.
9+
# Supported providers: anthropic, openai, google, custom
10+
#
11+
# For "custom" provider, AI_ENDPOINT is required.
12+
# For built-in providers, AI_ENDPOINT is optional (overrides default).
13+
#
14+
# OpenAI-compatible APIs (Groq, Together, Fireworks, Ollama, vLLM, LiteLLM)
15+
# can be used via the "custom" provider with the appropriate endpoint.
16+
17+
AI_PROVIDER=anthropic
18+
AI_API_KEY=sk-ant-...
19+
AI_MODEL=claude-sonnet-4-20250514
20+
AI_ENDPOINT=
21+
22+
# Examples for other providers:
23+
# AI_PROVIDER=openai
24+
# AI_API_KEY=sk-...
25+
# AI_MODEL=gpt-4o
26+
#
27+
# AI_PROVIDER=google
28+
# AI_API_KEY=AIza...
29+
# AI_MODEL=gemini-2.0-flash
30+
#
31+
# AI_PROVIDER=custom
32+
# AI_API_KEY= # leave empty for local models (e.g. Ollama)
33+
# AI_MODEL=llama3
34+
# AI_ENDPOINT=http://localhost:11434
1035

1136
# ─── CVE Data Feeds ───────────────────────────────────────────────────────────
1237
# NVD API key (free): https://nvd.nist.gov/developers/request-an-api-key
1338
NVD_API_KEY=
1439

15-
# ─── Auth (NextAuth.js) ───────────────────────────────────────────────────────
40+
# ─── Auth (SvelteKit) ────────────────────────────────────────────────────────
1641
# Generate with: openssl rand -base64 32
17-
NEXTAUTH_SECRET=change-me-in-production
18-
NEXTAUTH_URL=http://localhost:3000
42+
AUTH_SECRET=change-me-in-production
43+
AUTH_URL=http://localhost:5173
1944

2045
# GitHub OAuth (create at: github.com/settings/applications/new)
2146
GITHUB_CLIENT_ID=
@@ -33,5 +58,4 @@ STRIPE_PRO_PRICE_ID=price_...
3358
STRIPE_TEAM_PRICE_ID=price_...
3459

3560
# ─── App ──────────────────────────────────────────────────────────────────────
36-
NEXT_PUBLIC_APP_URL=http://localhost:3000
3761
ZENVRA_API_URL=http://localhost:8080

AGENTS.md

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ Zenvra (`zenvra.dev`) is an AI-powered code vulnerability scanner. It scans code
2222
```
2323
zenvra/
2424
├── apps/
25-
│ └── web/ # Next.js 15 frontend — scanner UI, dashboard, auth, billing
25+
│ └── web/ # SvelteKit 5 frontend — scanner UI, dashboard, auth, billing
2626
├── crates/
27-
│ ├── scanner/ # Rust core: SAST engine, SCA, secrets detection, CVE lookup
27+
│ ├── scanner/ # Rust core: SAST engine, SCA, secrets detection, CVE lookup, AI provider layer
2828
│ └── cli/ # Rust CLI: `zenvra scan`, `zenvra report`, `zenvra auth`
2929
├── extensions/
3030
│ └── vscode/ # VS Code extension: inline diagnostics, hover fixes
@@ -38,22 +38,59 @@ zenvra/
3838

3939
| Layer | Technology | Notes |
4040
|-------|-----------|-------|
41-
| Frontend | Next.js 15, TypeScript, Tailwind CSS | App Router. No Pages Router. |
42-
| UI components | shadcn/ui | Installed in apps/web/components/ui |
41+
| Frontend | SvelteKit 5, TypeScript, Tailwind CSS v4 | File-based routing. Svelte 5 runes syntax. |
4342
| Backend API | Rust, Axum | REST + SSE for streaming scan results |
4443
| Scan engine | Rust, Semgrep (via subprocess) | Custom rules in crates/scanner/rules/ |
45-
| Secrets detection | Rust, Gitleaks patterns | Compiled regex patterns |
46-
| AI explanations | Anthropic Claude API (claude-sonnet-4-20250514) | For CVE explanations and fix generation only |
44+
| Secrets detection | Rust, compiled regex patterns | Gitleaks-inspired patterns |
45+
| AI explanations | Multi-provider (Anthropic, OpenAI, Google, custom) | Bring-your-own-key supported. See AI Provider section. |
4746
| CVE database | NVD + OSV + GitHub Advisory DB | Synced daily via cron in scripts/sync-cve.sh |
48-
| Database | PostgreSQL 16 | Diesel ORM in Rust, Prisma in Next.js |
47+
| Database | PostgreSQL 16, sqlx | Compile-time checked async queries |
4948
| Cache / Queue | Redis 7 | Scan jobs via a simple queue pattern |
50-
| Auth | NextAuth.js v5 | GitHub + Google OAuth + email magic link |
49+
| Auth | TBD (SvelteKit-based) | GitHub + Google OAuth |
5150
| Payments | Stripe | Subscription billing |
5251
| CLI | Rust, Clap v4 | Produces single static binary |
5352
| VS Code ext | TypeScript, VS Code Extension API | LSP-style diagnostics |
5453

5554
---
5655

56+
## AI Provider System
57+
58+
Zenvra supports multiple AI providers for generating vulnerability explanations and fix suggestions. Users can bring their own API key and even configure custom endpoints.
59+
60+
### Supported Providers
61+
62+
| Provider | Models | Notes |
63+
|----------|--------|-------|
64+
| Anthropic | claude-sonnet-4-20250514, etc. | Default provider |
65+
| OpenAI | gpt-4o, gpt-4o-mini, etc. | Also works for OpenAI-compatible APIs (Groq, Together, etc.) |
66+
| Google | gemini-2.0-flash, etc. | Gemini generateContent API |
67+
| Custom | User-defined | Any endpoint with OpenAI-compatible API format |
68+
69+
### Configuration
70+
71+
```env
72+
AI_PROVIDER=anthropic # anthropic | openai | google | custom
73+
AI_API_KEY=sk-ant-... # API key for the chosen provider
74+
AI_MODEL=claude-sonnet-4-20250514 # Model identifier
75+
AI_ENDPOINT= # Only needed for custom provider or non-default endpoints
76+
```
77+
78+
### Architecture
79+
80+
The `AiProvider` trait in `crates/scanner/src/ai/` defines the interface:
81+
82+
```rust
83+
#[async_trait]
84+
pub trait AiProvider: Send + Sync {
85+
async fn explain(&self, finding: &RawFinding) -> Result<String>;
86+
async fn generate_fix(&self, finding: &RawFinding) -> Result<String>;
87+
}
88+
```
89+
90+
Each provider (`AnthropicProvider`, `OpenAiProvider`, `GoogleProvider`, `CustomProvider`) implements this trait. Provider selection is config-driven via `AiConfig`.
91+
92+
---
93+
5794
## Coding Rules — Always Follow These
5895

5996
### Rust
@@ -65,11 +102,10 @@ zenvra/
65102
- Tests in `#[cfg(test)]` modules at bottom of each file
66103
- No `unsafe` without a comment explaining exactly why it's safe
67104

68-
### TypeScript / Next.js
105+
### TypeScript / SvelteKit
69106
- TypeScript strict mode is ON — no `any`, no `@ts-ignore`
70-
- Named exports everywhere except Next.js page components
71-
- Server Components by default; add `"use client"` only when needed
72-
- API routes live in `apps/web/src/app/api/`
107+
- Named exports everywhere except SvelteKit page/layout components
108+
- Use Svelte 5 runes syntax (`$state`, `$derived`, `$effect`, `$props`)
73109
- No secrets or API keys ever in client-side code
74110
- All fetch calls go through typed API client functions in `apps/web/src/lib/api.ts`
75111
- Components max 200 lines — split into smaller ones if larger
@@ -93,11 +129,11 @@ API validates input + queues scan job (Redis)
93129
Rust scanner worker picks up job:
94130
├── SAST: run Semgrep with Zenvra ruleset
95131
├── SCA: parse dependency files → query OSV/NVD API
96-
└── Secrets: scan with Gitleaks regex patterns
132+
└── Secrets: scan with compiled regex patterns
97133
98134
Raw findings → CVE lookup (local DB + NVD fallback)
99135
100-
Claude API: generate plain-English explanation + corrected code
136+
AI Provider: generate plain-English explanation + corrected code
101137
102138
Results stored in PostgreSQL, streamed to client via SSE
103139
@@ -109,18 +145,16 @@ User sees: severity badge + CVE ID + explanation + fix + shareable card
109145
## Key Domain Types (Rust)
110146

111147
```rust
112-
pub struct ScanJob {
113-
pub id: Uuid,
148+
pub struct ScanConfig {
114149
pub code: String,
115150
pub language: Language,
116-
pub engines: Vec<ScanEngine>, // Sast, Sca, Secrets
117-
pub created_at: DateTime<Utc>,
151+
pub engines: Vec<Engine>,
152+
pub ai_config: Option<AiConfig>,
118153
}
119154

120155
pub struct Finding {
121156
pub id: Uuid,
122-
pub scan_id: Uuid,
123-
pub engine: ScanEngine,
157+
pub engine: Engine,
124158
pub cve_id: Option<String>, // e.g. "CVE-2025-12345"
125159
pub cwe_id: Option<String>, // e.g. "CWE-89"
126160
pub severity: Severity, // Critical, High, Medium, Low, Info
@@ -134,7 +168,7 @@ pub struct Finding {
134168
}
135169

136170
pub enum Severity { Critical, High, Medium, Low, Info }
137-
pub enum ScanEngine { Sast, Sca, Secrets, AiCode }
171+
pub enum Engine { Sast, Sca, Secrets, AiCode }
138172
pub enum Language { Python, JavaScript, TypeScript, Rust, Go, Java, /* ... */ }
139173
```
140174

@@ -149,15 +183,18 @@ Required in `.env` (see `.env.example`):
149183
DATABASE_URL=postgresql://localhost:5432/zenvra
150184
REDIS_URL=redis://localhost:6379
151185
152-
# AI
153-
ANTHROPIC_API_KEY=sk-ant-...
186+
# AI Provider (multi-provider — see AI Provider System section)
187+
AI_PROVIDER=anthropic
188+
AI_API_KEY=sk-ant-...
189+
AI_MODEL=claude-sonnet-4-20250514
190+
AI_ENDPOINT=
154191
155192
# CVE feeds
156193
NVD_API_KEY=...
157194
158-
# Auth (Next.js)
159-
NEXTAUTH_SECRET=...
160-
NEXTAUTH_URL=http://localhost:3000
195+
# Auth (SvelteKit)
196+
AUTH_SECRET=change-me-in-production
197+
AUTH_URL=http://localhost:5173
161198
GITHUB_CLIENT_ID=...
162199
GITHUB_CLIENT_SECRET=...
163200
@@ -171,8 +208,8 @@ STRIPE_WEBHOOK_SECRET=whsec_...
171208
## What NOT to Do
172209

173210
- Do NOT use `unwrap()` or `expect()` in library/API code
174-
- Do NOT put business logic in React components — it goes in server actions or API routes
175-
- Do NOT call the Claude API for anything other than explanation + fix generation (it's expensive)
211+
- Do NOT put business logic in Svelte components — it goes in server-side load functions or API routes
212+
- Do NOT call the AI API for anything other than explanation + fix generation (it's expensive)
176213
- Do NOT store raw code in the database longer than needed — scan results only
177214
- Do NOT add dependencies without discussion — keep the dependency tree lean
178215
- Do NOT break the existing API contract without a migration plan
@@ -182,7 +219,7 @@ STRIPE_WEBHOOK_SECRET=whsec_...
182219

183220
## Current Status
184221

185-
This repository is in **initial setup phase**. The structure, CI, and issue templates are being established. No production code exists yet. First milestone: working web paste scanner (MVP).
222+
This repository is in **active MVP development**. The scan engine foundation, multi-AI provider system, and secrets detection are being built. First milestone: working CLI scanner + web paste UI.
186223

187224
When in doubt about a decision, open a GitHub Discussion rather than assuming. We build deliberately.
188225

crates/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ tracing.workspace = true
2020
tracing-subscriber.workspace = true
2121
colored = "2"
2222
indicatif = "0.17"
23+
walkdir = "2"

0 commit comments

Comments
 (0)