Skip to main content

Overview

The storage API provides cloud object storage integration for source code upload/download and scan result archival. All objects are scoped to a project via the X-Project-UUID header and stored under <bucket>/<project-uuid>/. Storage is disabled by default. Enable it by setting storage.enabled: true in vigolium-configs.yaml. All endpoints return 503 Service Unavailable when storage is not configured.

Security

All storage operations enforce project-level isolation:
  • Every object path is prefixed with the authenticated project UUID (<bucket>/<project-uuid>/<key>). The project UUID comes from the X-Project-UUID header, set by server middleware, clients cannot override the prefix.
  • Keys and UUIDs are validated against path traversal (../, ..\\, ..) before any storage operation. Malicious keys are rejected with 400 Bad Request.
  • Presigned URLs are scoped to the requesting project, a presigned URL for project A cannot access objects in project B.

GCP Setup

Vigolium uses S3-compatible HMAC keys to talk to GCS. You need to create HMAC credentials from a service account, then configure them in vigolium-configs.yaml.

Step 1: Create HMAC Keys from a Service Account

If you have a service account JSON key (e.g. gcs-readwrite-key.json), activate it and create HMAC credentials:
This outputs an accessId and secret. Save both, the secret is only shown once.

Step 2: Create a GCS Bucket

Step 3: Configure Vigolium

Set the credentials and bucket name as environment variables:
Then configure ~/.vigolium/vigolium-configs.yaml:

Step 4: Verify Connectivity

AWS S3 / MinIO

For AWS S3, change the driver and region:
For self-hosted MinIO, set the endpoint explicitly:

Storage Object Layout

All objects are prefixed with the project UUID for multi-tenant isolation:
Result bundles use .tar.gz format (gzip-compressed tar), matching the vigolium db export --format bundle format.

CLI Usage

Source Download from Storage

Use gs:// URIs with --source to download and extract source code from cloud storage before scanning:
The archive is downloaded, extracted to a temp directory, and cleaned up after the scan completes. The source_type field in the DB records "gcs".

Result Upload to Storage

Add --upload-results to upload scan results to cloud storage after completion:
Results are uploaded to:
  • Native scans: gs://<project-uuid>/native-scans/<scan-uuid>/results.tar.gz
  • Agentic scans: gs://<project-uuid>/agentic-scans/<run-uuid>/results.tar.gz
The storage_url field on the Scan / AgenticScan DB record is updated with the gs:// URL after upload.

POST /api/storage/upload-source

Uploads a source code archive to cloud storage, scoped to the project. Content-Type: multipart/form-data
Response (200):
The returned storage_url can be passed directly to --source (CLI) or the source field (API).

GET /api/storage/source/:key

Downloads a previously uploaded source file.
Returns the file as application/octet-stream with Content-Disposition: attachment. Returns 400 if the key contains path traversal sequences.

GET /api/storage/results/:scan-uuid

Downloads the result bundle for a native scan or agentic scan. Searches native-scans/<uuid>/results.tar.gz first, then agentic-scans/<uuid>/results.tar.gz.
Returns application/gzip with Content-Disposition: attachment. Returns 404 if no results have been uploaded for the given UUID. Extract the bundle:

POST /api/storage/presign

Generates a presigned URL for direct upload or download, bypassing the API server. Useful for large files or client-side uploads. Request body:
Response (200):
Keys are validated against path traversal, requests with ../ or similar sequences are rejected with 400.

Using Storage with Agentic Scans (API)

Upload Source, Then Run Agentic Scan

Run Autopilot with Local Source + Upload Results

Run Swarm with GCS Source


Storage URL in Scan Records

When upload_results is enabled, the storage_url field is populated on the Scan or AgenticScan record after upload completes. Native scan:
Agentic scan: