40 Commits

Author SHA1 Message Date
brandon
e419fb5d56 feat: add provider scaffold script 2026-03-20 13:28:51 -04:00
brandon
e3f112da3a fix: resolve TypeScript errors from structure refactoring
- notifications.ts: update severity-utils import to lib/utils/ path
- cleanup.ts: define MAX_BATCH_ITERATIONS locally in orphan cleanup method
- repositories/route.ts: coalesce nullable Zod fields with ?? undefined
- generate-openapi.ts: update import to lib/api/ path
- Remove stale .next type cache for old /api/image/ routes
2026-03-18 14:18:00 -05:00
brandon
a1dbd516b2 refactor: move test-registry-providers.ts to scripts/ 2026-03-12 13:56:00 -05:00
brandon
76b75f6532 fix: add support for EOL Debian archive repositories
- Detect and update sources.list for EOL Debian versions (stretch, jessie, wheezy)
- Replace deb.debian.org and security.debian.org with archive.debian.org
- Remove -updates repositories which don't exist in archives
- Fix single-line command format to avoid quote escaping issues
- Add test script to verify archive repository updates

This fixes the 404 errors when patching containers based on EOL Debian versions
like Debian 9 (Stretch) where the regular repositories are no longer available.
2025-09-29 23:39:34 -04:00
brandon
86036642e7 Fix patch commands to actually update packages
The previous implementation reported success but packages weren't actually
being updated. The issues were:
1. Commands were failing silently with || chaining
2. Version-specific installations weren't working on old Debian releases
3. No proper error reporting for failed package installations

Changes:

PatchExecutorTarUnshare.ts:
- Simplified APT command generation
- Use dist-upgrade and upgrade for better package updates
- Group packages to avoid duplicate processing
- Remove complex version-specific logic that doesn't work on old repos

Bash Scripts (buildah-patch-dev.sh and buildah-patch-container.sh):
- Add proper error detection and reporting
- Count failed commands and report them
- Show exit codes for failed commands
- Mark package installation failures as critical errors
- Return PATCH_STATUS:PARTIAL if any commands fail

This ensures:
- Packages are actually upgraded to fix vulnerabilities
- Failures are properly detected and reported
- No false success reports when patches don't apply
- Better visibility into what's actually happening

The simplified approach uses dist-upgrade/upgrade which will update
packages to their latest available versions in the repository, which
should include the security fixes.
2025-09-29 23:19:54 -04:00
brandon
02e28ba486 Add comprehensive debug output for patch operations
Enhanced logging to provide full visibility into patch execution:

TypeScript (PatchExecutorTarUnshare.ts):
- Added Patch Execution Summary showing total vulnerabilities, commands executed, and strategy
- Added error details logging for failed operations
- Added Final Patch Summary with operation ID, image details, and patched CVEs
- Shows clear indication when selective patching is used
- Displays warning that only selected CVEs were patched

Bash Scripts (buildah-patch-dev.sh and buildah-patch-container.sh):
- Added DEBUG: Patch Context showing container, mountpoint, and command details
- Added per-command execution tracking with [1], [2], etc. prefixes
- Shows Success/Warning status for each command
- Added DEBUG: Execution complete summary with total commands executed

This provides complete transparency for debugging and verification:
- What was requested vs what was actually patched
- Which specific commands succeeded or failed
- Clear indication of selective vs full patching
- Detailed execution context for troubleshooting
2025-09-29 22:42:05 -04:00
brandon
a04bbc2f5a Implement robust patch command execution to prevent quote escaping issues
- Changed command format from single line with && to newline-separated commands
- Updated PatchExecutorTarUnshare.ts to generate simpler commands without complex nesting
- Modified both buildah scripts to read and execute commands line by line
- Created execute-patch-commands.sh helper script for cleaner execution
- Split complex apt-get commands into simpler individual operations
- Process packages individually for better error handling and debugging

This robust approach completely avoids shell quote escaping issues by:
1. Writing commands to a file with newline separation
2. Reading and executing each command individually
3. Using parameter substitution instead of complex eval operations
2025-09-29 22:17:00 -04:00
brandon
1c2ea0a845 Fix patch script quote escaping issue
- Changed patch command execution to use file-based approach instead of inline commands
- Modified PatchExecutorTarUnshare.ts to write commands to a temporary file
- Updated both buildah-patch-dev.sh and buildah-patch-container.sh to read commands from file
- This avoids shell quote escaping issues when complex commands contain nested quotes

The issue occurred because patch commands containing sh -c with quoted arguments were
being passed as a single-quoted string to the bash scripts, causing syntax errors
when the inner quotes conflicted with the outer quotes.
2025-09-29 22:05:56 -04:00
brandon
6d598798ea refactor: update remaining components for registry system integration
- Updated UI components to work with new repository structure
- Fixed bulk scan service to use new registry handlers
- Updated patch executors to use registry providers
- Added migration scripts for registry references
- Updated type utilities and database service
- Regenerated OpenAPI spec with new endpoints
2025-09-12 02:23:58 -04:00
brandon
42ee1ae9d4 refactor: move tag data from images table to scans table
- Add tag field to Scan model with default "latest"
- Create database migration and indexes for performance
- Update APIs to include scan.tag field in responses
- Fix home page to show only image names instead of image:tag
- Update image details page to query tags from scans table
- Fix React key warnings and undefined tag handling
- Update scanner services to use scan.tag instead of image.tag
- Add data migration script for existing scan records

This change enables proper support for multiple tags per image
by storing tag information at the scan level rather than image level.
2025-09-10 23:13:20 -04:00
brandon
38912fb0a6 Fix TypeScript errors in test data replication script
- Changed BigInt types to regular numbers for compatibility
- Added proper null checking for Prisma findUnique results
- Fixed production build errors

These changes allow the application to build successfully for production.
2025-09-09 20:44:00 -04:00
brandon
843715cab1 fix: show total database count in section cards instead of current page count
- Removed unused showExpanded state from DataTable component
- Updated useScans hook to use total count from database pagination
- Section cards now show "X of 103 scans completed" instead of "X of 25"
- Shows accurate total count regardless of current page
2025-09-09 20:05:10 -04:00
brandon
0b634c3a6c Fix patch permissions issue with chroot environment
- Mount /dev, /proc, /sys, /run into chroot before patching
- Create minimal device nodes if bind mount fails
- Mount /dev/pts for proper terminal allocation
- Install GPG tools and apt-utils before running apt-get update
- Copy resolv.conf for DNS resolution in chroot
- Properly cleanup all mounts after patching

Fixes permission denied errors when accessing /dev/null, GPG
verification failures, and terminal allocation warnings during
apt operations in chroot environment.
2025-09-09 09:20:02 -04:00
brandon
8cb818fcba Remove unused API endpoints and scripts
- Remove 4 unused API endpoints:
  - /api/scans/[id]/optimized
  - /api/scans/[id]/packages
  - /api/scans/[id]/findings/packages
  - /api/scans/[id]/findings/compliance

- Remove unused scripts and test files
- Remove old export-image-dialog component (replaced with enhanced version)
- Clean up environment variables in .env files
2025-09-08 09:39:26 -04:00
brandon
7d06ece920 feat: Enhanced export functionality and buildah patching improvements
- Add Docker Local export option with socket detection
- Preserve tar files after scanning for patching operations
- Improve tar file discovery with multiple naming patterns
- Add registry authentication support for exports
- Remove test files and unnecessary documentation
- Fix tar cleanup issues preventing patch operations
2025-09-07 23:59:58 -04:00
brandon
fefe00806e fix: Resolve Alpine APK network issues in buildah patching
- Added DNS resolution setup by copying /etc/resolv.conf to chroot
- Fixed libssl3/libcrypto3 co-dependency handling for Alpine
- Verified patching works with test script (3.0.8-r3 -> 3.0.15-r1)
- Network connectivity now properly established in chroot environment

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-07 15:13:47 -04:00
brandon
43f93334de fix: Use buildah unshare for rootless patch operations
- Created buildah-patch-full.sh script for complete patch workflow in unshare
- Added PatchExecutorTarUnshare class for simplified unshare-based patching
- Fixed permission errors by running all buildah operations in user namespace
- Simplified patch command generation for different package managers
- Updated API to use new unshare executor

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-07 15:09:55 -04:00
brandon
dc27999ffd fix: Add missing Alert UI component
- Created Alert, AlertTitle, and AlertDescription components
- Used for displaying patch analysis status messages
- Follows existing UI component patterns with class-variance-authority
2025-09-07 14:57:20 -04:00
brandon
b813e230ee feat: Add tar-based patching workflow for Buildah integration
- Created PatchExecutorTar that works with existing Skopeo tar workflow
- Integrates with scan tar files from /workspace/images directory
- Exports patched images as tar files for repository upload
- Added buildah-patch.sh wrapper script for unshare operations
- Supports local Docker images and registry images
- Added download endpoint for patched tar files
- Saves patch reports alongside scan results

This aligns with the existing HarborGuard workflow:
1. Skopeo downloads image as tar
2. Scanners analyze the tar
3. Patch executor modifies the tar using Buildah
4. Patched tar can be pushed to registry with Skopeo
2025-09-07 14:44:12 -04:00
brandon
5a3d39c256 fix: Extract actual license values instead of 'declared' from Syft data
- Updated formatLicense to prioritize 'value' and 'spdxExpression' fields
- Skip 'type' field which contains 'declared' instead of actual license
- Added debug logging to track license processing
- Created scripts to fix existing data with wrong license values

Note: Changes require server restart to take effect in development mode
2025-09-05 12:31:46 -04:00
brandon
33d4fef356 fix: Properly handle license field as object in package findings
- Added formatLicense helper to DatabaseAdapter to handle various license formats
- Fixed migration script to properly format licenses
- Created fix-package-licenses script to clean up existing bad data
- Prevents storing '[object Object]' as license value in database
- Handles licenses as string, array, or object structures
2025-09-05 11:52:19 -04:00
brandon
ecdc47adaf feat: Add normalized scanner finding tables and APIs
- Created 5 new tables for normalized scanner findings:
  - ScanVulnerabilityFinding: Store vulnerabilities by source
  - ScanPackageFinding: Store package/SBOM data
  - ScanComplianceFinding: Store compliance violations
  - ScanEfficiencyFinding: Store efficiency/optimization findings
  - ScanFindingCorrelation: Track cross-scanner consensus

- Migrated existing scan data to new tables:
  - 147 vulnerability findings
  - 1774 package findings
  - 3 compliance findings
  - 5 efficiency findings
  - 64 correlations

- Created API endpoints for querying findings:
  - /api/scans/[id]/findings/vulnerabilities
  - /api/scans/[id]/findings/packages
  - /api/scans/[id]/findings/compliance

- Added VulnerabilityFindings React component with:
  - Grouped view showing multi-scanner consensus
  - All sources view showing individual findings
  - Confidence scoring based on scanner agreement
  - Visual indicators for severity and sources
2025-09-05 10:48:40 -04:00
brandon
ae96072e98 refactor: Remove unused PolicyRule and PolicyViolation tables
- Removed PolicyRule and PolicyViolation models from Prisma schema
- Removed PolicyCategory enum which was only used by these tables
- Updated TypeScript types to remove references to these models
- Removed relations to these tables from Scan model
- Created and applied migration to drop the database tables
- All 12 remaining tables are actively used in the application
2025-09-05 10:08:11 -04:00
brandon
44e2759274 fix: Update download endpoints to use metadata relation
- Include metadata relation when fetching scans
- Access scanner results from metadata table
- Update both individual report and ZIP download endpoints
2025-09-05 08:52:05 -04:00
brandon
b243672605 refactor: Move scan metadata to dedicated table with foreign key relationship
- Created new ScanMetadata table with properly typed columns
- Changed scan.metadata from JSON blob to foreign key reference
- Migrated existing data preserving all information
- Updated all code to use new relational structure
- Improved type safety and query performance
2025-09-04 23:01:14 -04:00
brandon
9b69e0b7fd refactor: Move scan metadata from JSON column to dedicated table
- Created new ScanMetadata table with properly typed columns
- Migrated existing metadata from JSON to structured columns
- Updated DatabaseAdapter to use new ScanMetadata table
- Modified API routes to include scanMetadata relation
- Improved performance with indexed columns
- Maintained backward compatibility during migration

Benefits:
- Better query performance with indexed columns
- Type-safe database queries
- Easier to query specific metadata fields
- Reduced JSON parsing overhead
2025-09-04 22:43:35 -04:00
brandon
685805d2c6 fix: Resolve database authentication mismatch for bundled PostgreSQL
## Problem
The bundled PostgreSQL database was failing with authentication errors due to
credential mismatches between start.sh and init-database-with-fallback.js scripts.

## Root Cause
- start.sh was generating a random password for each container start
- init-database-with-fallback.js was using hardcoded credentials
- When PostgreSQL persisted between restarts, the passwords would mismatch

## Solution
- Modified init-database-with-fallback.js to use environment variables for credentials
- Updated start.sh to use consistent default password for bundled PostgreSQL
- Both scripts now use POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB variables

## Changes
- init-database-with-fallback.js: Use environment variables for PostgreSQL credentials
- start.sh: Use fixed default password instead of random generation for bundled DB

This ensures consistent authentication whether PostgreSQL is freshly initialized
or already running from a previous container start.
2025-09-01 22:55:18 -04:00
brandon
0de5cd655a feat: Remove SQLite support and fix Trivy cache configuration
- Removed all SQLite references and functionality
- PostgreSQL is now the only supported database
- Fixed Trivy cache directory mismatch between Dockerfile and runtime
- Updated cache directories to use /workspace/cache consistently
- Added Docker resource limits (2 CPU cores, 4GB RAM) to docker-compose.yml
- Updated documentation to reflect PostgreSQL-only support
- Fixed HOSTNAME binding issue for Windows WSL connectivity
- Improved database initialization scripts for PostgreSQL-only operation
- Updated .gitignore to exclude PostgreSQL data directory instead of SQLite files
- Ensured Prisma client generation at build time

Breaking changes:
- SQLite databases are no longer supported
- DATABASE_URL must now point to a PostgreSQL instance or be omitted for bundled PostgreSQL
2025-09-01 16:25:22 -04:00
brandon
7cdaf2e7c7 refactor: Clean up Dockerfile and improve PostgreSQL setup
- Moved startup script from inline Dockerfile to separate start.sh file
- Removed hardcoded PostgreSQL credentials from Dockerfile
- Auto-generate secure passwords for bundled PostgreSQL if not provided
- Fixed password generation to avoid special characters that break URLs
- Added OpenSSL to dependencies for secure password generation
- Improved separation of concerns with cleaner Dockerfile

The container now:
- Generates secure random passwords automatically if not provided
- Uses environment variables for all PostgreSQL configuration
- Has a cleaner, more maintainable Dockerfile
- Properly handles special characters in database URLs
2025-09-01 15:02:14 -04:00
brandon
41a25ad605 feat: Add automatic fallback to bundled PostgreSQL
- DATABASE_URL is now optional - if not provided, uses bundled PostgreSQL
- If external DATABASE_URL is provided but connection fails, automatically falls back to bundled PostgreSQL
- Created init-database-with-fallback.js script that tests external connections
- Updated startup script to conditionally start bundled PostgreSQL
- Made docker-compose.yml database configuration optional with comments

This allows users to:
1. Run without any database configuration (uses bundled PostgreSQL)
2. Connect to external PostgreSQL when available
3. Automatically fallback to bundled PostgreSQL if external DB is unavailable
2025-09-01 14:04:27 -04:00
brandon
9196834317 feat: Replace SQLite with PostgreSQL as default database
- Updated Prisma schema to use PostgreSQL provider
- Modified Dockerfile to bundle PostgreSQL 16 in the image
- Simplified init-database.js for PostgreSQL only
- Updated environment variables in .env and docker-compose.yml
- Created PostgreSQL migration files
- Configured automatic PostgreSQL initialization on container start

The application now includes a bundled PostgreSQL database that automatically
initializes on first run, eliminating the need for external database setup.
2025-09-01 13:54:17 -04:00
brandon
53062a909b fix: Remove duplicate fs declaration causing PostgreSQL connection failure
Root Cause Analysis:
The init-database.js script had a duplicate 'fs' constant declaration on line 78
within the testPostgreSQLConnection function. Since 'fs' was already imported
at the module level (line 3), this redeclaration caused a ReferenceError:
"Cannot access 'fs' before initialization" when attempting PostgreSQL connections.

Why PR #26 didn't suffice:
PR #26 successfully added PostgreSQL support and the connection logic was sound.
However, during subsequent refactoring to improve the connection test mechanism,
a duplicate 'const fs = require('fs')' was inadvertently added inside the
testPostgreSQLConnection function. This scoping issue prevented the PostgreSQL
connection test from executing properly, causing all PostgreSQL connections to
fail and fall back to SQLite.

Resolution:
Removed the duplicate fs declaration from line 78, allowing the function to use
the module-level fs import. This restores full PostgreSQL connectivity.

Fixes #30
2025-09-01 06:06:48 -04:00
brandon
c795fd24f2 Fix API documentation in containerized deployments
The API docs were not showing any endpoints when running in Docker containers
because the standalone Next.js build doesn't include source files needed for
dynamic API route scanning.

Changes:
- Add build-time OpenAPI spec generation script
- Generate static OpenAPI spec during Docker build
- Update API route to use pre-generated spec in production
- Modify package.json with separate build commands for Docker
- Add debug logging for troubleshooting API scanning issues

This ensures the full API documentation with all 39 endpoints is available
in both development and production containerized environments.
2025-08-31 21:25:39 -04:00
brandon
f2565a9597 Fix Prisma provider mismatch causing PostgreSQL connection failures
Regenerate Prisma client immediately after updating schema provider to ensure
the generated client matches the database type being used. This resolves the
issue where PostgreSQL URLs were being used with a SQLite-generated client,
causing 'URL must start with protocol file:' errors.

Changes:
- Generate Prisma client right after updateSchemaProvider() in both SQLite and PostgreSQL initialization
- Update PostgreSQL connection test to use correct provider during testing
- Remove redundant prisma generate call at the end of initialization

This ensures the Prisma client binary always matches the active database provider
before any database operations are attempted.

Fixes #23
2025-08-31 15:43:51 -04:00
brandon
f80fd6b8aa Fix Prisma CLI not found in Docker runtime
- Install Prisma CLI globally in runtime container
- Update init-database.js to check Prisma availability
- Change npx prisma calls to direct prisma calls for efficiency
- Minimal size impact (~20-25MB) by installing only required engine

Fixes #23
2025-08-31 10:48:58 -04:00
brandon
bbcf60f986 fix: Add PENDING status to ScanStatus enum and documentation
- Added PENDING to ScanStatus enum in Prisma schema
- Added comprehensive queue implementation documentation
- Added test script to demonstrate queue functionality
- Updated gitignore to exclude dev.db
2025-08-30 19:53:38 -04:00
brandon
a90c51778b Removing test files 2025-08-28 01:38:17 -04:00
brandon
9d0e8a392c test: Add OSV-scanner independence verification script
- Created test script to verify OSV-scanner and Syft availability
- Confirms the independence implementation allows parallel execution
- Both scanners are properly installed and functional
2025-08-28 01:35:57 -04:00
brandon
81f2c1a561 Implement conditional database setup with PostgreSQL/SQLite support
- Add comprehensive database detection and initialization system
- Support both SQLite (default) and PostgreSQL with automatic fallback
- Create database initialization script with connection testing
- Add SSL certificate handling for managed PostgreSQL databases (DigitalOcean)
- Update Dockerfile to use conditional database initialization at runtime
- Add database management scripts to package.json (db:init, db:migrate, etc.)
- Create comprehensive DATABASE.md documentation with setup examples
- Update README.md with database configuration information
- Add environment configuration examples for both database types

Key features:
- Automatic provider detection from DATABASE_URL environment variable
- Graceful fallback to SQLite when PostgreSQL connection fails
- Proper SSL handling for cloud PostgreSQL services
- Runtime schema provider switching for optimal compatibility
- Production-ready Docker deployment with external database support
- Maintains 100% backward compatibility with existing SQLite deployments

Technical implementation:
- Database detection utility functions with connection testing
- Dynamic Prisma schema provider updates based on detected database
- Separate initialization strategies for SQLite vs PostgreSQL
- Error handling and logging for troubleshooting connection issues
- Support for DigitalOcean managed databases with self-signed certificates
2025-08-25 22:49:25 -04:00
brandon
299ef56602 Add complete Harbor Guard codebase
- Next.js 15 + React 19 web application
- Multi-tool container security scanning (Trivy, Grype, Syft, Dockle, OSV, Dive)
- Interactive vulnerability visualization with scatter plots
- Historical scan tracking and comparison
- Report export functionality (individual JSON + ZIP packages)
- Real-time scan progress monitoring
- Docker integration with local image scanning
- REST API endpoints for programmatic access
- Modern UI with Tailwind CSS + shadcn/ui components
- Prisma ORM with SQLite database
- TypeScript for type safety
2025-08-14 15:23:50 -04:00