Skip to content

fix(security): address security review findings - #2

Merged
venice-dev[bot] merged 48 commits into
soli-testbench:mainfrom
Chris-Moller:agent/b3e9f055-f46a-4c2a-a9ef-4e3befc6dde0
Mar 25, 2026
Merged

fix(security): address security review findings#2
venice-dev[bot] merged 48 commits into
soli-testbench:mainfrom
Chris-Moller:agent/b3e9f055-f46a-4c2a-a9ef-4e3befc6dde0

Conversation

@Chris-Moller

@Chris-Moller Chris-Moller commented Mar 25, 2026

Copy link
Copy Markdown

Security review decision: needs_review

Claude: The branch scaffolds the Chief MOG Officer monorepo (apps/web, apps/api, apps/worker, shared packages, DB schema, docs) matching the task's acceptance criteria. Scope match is minor deviation: .agent-compose/ metadata files are committed despite being gitignored, and the Dockerfile is present though not explicitly in scope — both are benign. Security posture is sound: (1) No outbound network egress — all fetch calls target the local API backend only, Google Fonts removed; (2) Auth middleware enforces JWT HS256 verification with mandatory JWT_SECRET in production, no fallback secrets; (3) No install hooks, eval/exec, child_process, or dynamic code execution in any application code; (4) SQL migration contains only CREATE TABLE/INDEX/ALTER statements with no destructive operations; (5) Config rejects weak DB credentials in production via Zod validation. Heuristic pre-filter signals (prompt injection, supply chain) are false positives from workflow YAML and package-lock.json contents.

Codex: Task compliance: mostly within scope for MVP scaffolding, but with minor deviation from trusted context due committed agent-operational artifacts under .agent-compose/ that are unrelated to product scaffolding. Security posture: no clear backdoor/exfil/destructive primitives found in app code (no install hooks in package scripts; no eval/child_process; migration is CREATE/ALTER-only), but integrity is unclear because prompt-like reviewer guidance is committed in-repo and API analysis route can report queued status after queue failure via mock job ID. Assessment: within scope but safety unclear, so escalate for manual review.

Findings

  • [low] .agent-compose/AGENT_HISTORY.md: Agent metadata committed despite gitignore. Benign content (history logs), no secrets. Minor hygiene issue only.
  • [low] apps/api/src/middleware/auth.ts: Exports active JWT secret for test use. Only callable server-side, documented as test-only. Low risk but could be removed in production builds.
  • [medium] .agent-compose/security-fixer-20260325T022718Z/CLAUDE.md: Out-of-scope prompt-like operational content in the repo can bias automated reviewers and creates integrity noise not required by task acceptance.
  • [low] .gitignore: Mismatch indicates process-control artifacts were intentionally/accidentally tracked despite exclusion policy; increases review surface and hidden-context risk.
  • [low] apps/api/src/routes/analysis.ts: Failure is masked as queued success; can mislead operators and obscure real processing outages. Not covert, but degrades operational integrity.

Recommended Actions

  • Add a CI guard to block prompt-like operational artifacts (e.g., .agent-compose/**) from commits.
  • Change /projects/:id/analyze to return explicit failure when queue enqueue fails, or mark response as simulated.
  • Consider removing getActiveJwtSecret() export or gating it behind NODE_ENV=test
  • Re-run security review after artifact removal and failure-path hardening.
  • Remove .agent-compose/ tracked files (they are gitignored and should not be committed)
  • Remove committed .agent-compose/ files from the branch and keep them untracked.
  • Verify all 89 tests pass in CI before merge

Venice Agent and others added 29 commits March 25, 2026 00:33
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define Zod 4 schemas, inferred TypeScript types, and insert schemas
for all 10 domain entities: User, Project, CompanyProfile,
NarrativeModel, CompetitorProfile, Opportunity, Asset, Campaign,
AgentRun, and DailyDigest. Barrel export from index.ts with .js
extensions for ESM compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… utilities

- packages/config: Zod-based environment variable validation with dotenv
- packages/lib/logger: structured logger with JSON (prod) and pretty (dev) output
- packages/lib/errors: AppError base class with NotFound, Validation, Unauthorized subclasses
- packages/lib/utils: generateId (uuid v4), sleep, and retry with exponential backoff
- Added @types/node to root devDependencies for TypeScript compilation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add docker-compose.yml (PostgreSQL 16 + Redis 7), multi-stage Dockerfile,
and four documentation files: architecture overview, domain model reference,
agent interface contract, and developer setup guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create the apps/worker package with:
- Redis connection helper (src/lib/redis.ts)
- runAgent job to execute a single agent (src/jobs/run-agent.ts)
- runAnalysis job to orchestrate all agents for a project (src/jobs/run-analysis.ts)
- Analysis queue worker using BullMQ (src/workers/analysis.ts)
- Scheduled daily analysis via cron (src/workers/scheduled.ts)
- Entry point with graceful shutdown (src/index.ts)
- Unit tests with mocked agents and lib (/__tests__/worker.test.ts)
- package.json and tsconfig.json configuration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement the @chief-mog/agents package with:
- Agent interface types (AgentContext, IngestResult, AnalysisResult, Agent)
- Map-based agent registry with register/get/getAll functions
- 5 stub agents (SearchMog, Geo, RedditMog, CompetitorIntel, ContentFoundry)
  each implementing full Agent interface with realistic mock data
- Barrel export that triggers agent registration on import
- Comprehensive test suite (27 tests) verifying registry and interface compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hells

- Bootstrapped Vite + React 19 + React Router 7 + Tailwind v4 app
- Implemented Command Dark design system with custom CSS tokens
- Created shadcn/ui-style components (button, card, input, table, badge, select, textarea, label)
- Built app shell with fixed sidebar navigation and root layout
- Created Command Center page with metric cards, activity feed, quick actions
- Created Project Creation page with form (name, description, company, industry, website, keywords)
- Created Opportunity List page with data table, status badges, and score indicators
- Added API client stub with mock data for standalone frontend development
- Created shared components (page-header, status-badge, empty-state)
- Set up packages/types with all domain Zod schemas and TypeScript types
- Set up packages/ui with cn() utility export
- All 12 tests pass, TypeScript compiles clean, production build succeeds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement the complete Hono HTTP API server at apps/api/ including:
- Server entry point with @hono/node-server
- Hono app with CORS, request logging, and global error handling
- Auth middleware (placeholder, checks Authorization header)
- Health check route (GET /health)
- Project CRUD routes with mock data and Zod validation
- Analysis route that enqueues BullMQ jobs with Redis fallback
- Opportunities route returning mock data
- BullMQ queue connection helper
- Full test suite (9 tests) using Hono's built-in test client

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set up the complete monorepo infrastructure:
- Root config: package.json with npm workspaces, turbo.json, tsconfig.base.json, biome.json
- packages/types: Zod schemas and TS types for all 10 domain models
- packages/config: Zod-validated environment configuration
- packages/lib: Logger, AppError classes, generateId/sleep/retry utilities
- packages/db: Drizzle ORM schema, connection, and seed script
- packages/ui: Placeholder for shared React components
- apps/web: Placeholder for frontend app
- Docker Compose (PostgreSQL + Redis) and multi-stage Dockerfile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Root config: Turborepo, npm workspaces, TypeScript, Biome, vitest
- packages/types: Zod schemas + TS types for all 10 domain models
- packages/config: Zod-based environment validation with lazy parse
- packages/lib: Logger, error classes (AppError, NotFound, etc.), utilities
- packages/db: Drizzle ORM schema for all tables, migration, seed script
- Placeholder apps (web, api, worker) and packages (ui, agents)
- All builds, tests (33 passing), lint, and typecheck pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Mark all backend checklist items (b1-b7) as passing in tasks.json
- Add AGENT_HISTORY.md with completion summary
- Add --passWithNoTests to packages without test files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Delete unused error middleware (apps/api/src/middleware/error.ts) — error
  handling is done via app.onError, making this file dead code
- Extract isAppError() type guard into @chief-mog/lib and use it in app.ts
  to consolidate duplicate duck-type checking logic
- Remove unused getAllAgents import from run-agent.ts
- Simplify seed.ts runIds construction with .map() instead of for loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged backend implementation (API, worker, agents) with foundation branch.
Conflict resolution strategy:
- Backend-owned: apps/api, apps/worker, packages/agents -> took backend version
- Foundation-owned: packages/types,config,lib,db,ui -> kept foundation version
- Root config: merged best of both (foundation Dockerfile + backend scripts)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged frontend implementation (React app, UI package) with foundation+backend.
- apps/web: took frontend's real React implementation
- packages/ui: took frontend's real implementation with cn utility
- packages/types: kept foundation's modular approach
- Root config: kept integrated version from previous merge

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add isAppError() type guard to @chief-mog/lib for backend API error handling
- Fix frontend mock data to use Date objects (matching foundation's z.date() types)
- Fix web test setup to manually extend vitest matchers (vitest v3/v4 compat)
- Exclude test files from web app build tsconfig
- Fix ioredis/bullmq type incompatibility in worker redis connection
- Update biome.json to v2.4.8 format with Tailwind CSS support
- Auto-format all packages with biome (import ordering, line width)
- Suppress noLabelWithoutControl for shadcn Label component pattern

Build: 9/9 packages compile
Typecheck: 9/9 pass
Lint: 9/9 pass (1 warning)
Tests: 85 tests across 7 packages, all passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove out-of-scope .agent-compose operational artifacts (init.sh, tasks.json)
  that introduced side-effectful execution paths and prompt-like payloads
- Remove root tasks.json containing prompt-like instruction content
- Harden auth middleware: reject missing Bearer prefix, empty tokens, and
  known placeholder values; add TODO for real token validation
- Remove hardcoded 'Bearer placeholder' from frontend API client; use
  VITE_API_TOKEN env var instead with TODO for proper auth flow
- Make CORS origin configurable via CORS_ORIGIN env var with TODO to
  restrict before production
- Add rate limiting TODO to API route declarations
- Parameterize docker-compose credentials via env vars with dev defaults;
  add safety comment about production use

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Chris-Moller Chris-Moller changed the title feat: integrate monorepo foundation, backend API, and frontend app fix(security): address security review findings Mar 25, 2026
Venice Agent and others added 19 commits March 25, 2026 02:03
- Replace placeholder auth with real JWT verification (HS256) using
  hono/jwt — validates signature, expiry, issuer, and audience claims
- Add in-memory rate limiting middleware on /api/* (100 req/min per IP)
  with standard X-RateLimit-* headers
- Restrict CORS to explicit origin in production (wildcard only in dev/test)
- Add env validation rejecting default DB credentials in production
- Add security tests: reject arbitrary tokens, expired tokens, wrong-secret tokens
- Remove committed .tsbuildinfo artifacts (already in .gitignore)
- Remove .agent-compose operational artifacts and add ignore rules
- Update .env.example with JWT config docs and security notes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace predictable hardcoded JWT dev fallback with random per-instance
  secret (crypto.randomBytes), eliminating token forgery risk from
  known default secret
- Remove VITE_API_TOKEN client-side bearer pattern; switch to
  cookie-based session auth (credentials: "include") to prevent
  static token exposure in frontend builds
- Remove .agent-compose/AGENT_HISTORY.md from source control and
  gitignore entire .agent-compose/ directory
- Add production startup guards: API refuses to start without
  JWT_SECRET and CORS_ORIGIN in production
- Expand .gitignore to cover .env.* variants (preserving .env.example)
- Document threat model, auth expectations, and deployment checklist
  in docs/dev-setup.md
- Update .env.example to reflect new secret generation guidance
- Update API tests to use getActiveJwtSecret() instead of hardcoded value

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Gate mock API fallbacks behind explicit VITE_MOCK_API=true env flag
  instead of silently catching all request errors. API methods now throw
  on failure unless mock mode is explicitly enabled.
- Align frontend auth contract with backend: use Bearer JWT tokens via
  Authorization header instead of cookie-based credentials:"include".
  Added setAuthToken() for in-memory token management.
- Remove third-party Google Fonts egress from index.html; replaced with
  system font stacks in CSS to eliminate external runtime dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove tracked .agent-compose/ files from git (they are gitignored)
- Gate getActiveJwtSecret() export behind NODE_ENV=test guard
- Change /projects/:id/analyze to return 503 on queue failure instead of
  masking the error with a mock job ID
- Update analysis test to expect 503 when queue is unavailable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Require exp claim in JWT validation — tokens without expiry are now rejected
- Parse full REDIS_URL (username/password/TLS/db) in API queue client
- Parse full REDIS_URL (username/password/TLS/db) in worker Redis client
- Add DB persistence of AgentRun lifecycle (pending→running→completed/failed)
- Fix docs to describe actual JWT Bearer auth model (was incorrectly documenting cookie-based auth)
- Add test for exp-required JWT validation and DB mocks for worker tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix TypeScript build error in apps/worker/src/lib/redis.ts by replacing
the invalid `ConstructorParameters<typeof IORedis>[0]` cast with proper
`RedisOptions` type import from ioredis. The previous cast resolved to an
empty tuple type, causing TS2352/TS2769/TS2493 errors during CI build.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove .agent-compose/ tracked files (git rm --cached) to honor .gitignore
- Harden rate limiter: proxy headers (X-Forwarded-For, X-Real-IP) are now only
  trusted when TRUST_PROXY env var is explicitly set to "true" or "1"; otherwise
  uses socket remote address from @hono/node-server to prevent IP spoofing
@venice-dev
venice-dev Bot merged commit 82e0a84 into soli-testbench:main Mar 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant