Documentation
¶
Overview ¶
Package server implements the REST API server (built on Fiber): traffic ingestion endpoints, scan and findings APIs, the agent run API, project scoping via the X-Project-UUID header, and the bundled Swagger UI. Handlers are composed from focused sub-structs and delegate scanning to pkg/core and agent runs to pkg/agent. See docs/server-mode/.
Index ¶
- Constants
- Variables
- func AuthorHeaderMiddleware(author string) fiber.Handler
- func BearerAuth(validKeys []string, store *UserStore) fiber.Handler
- func BootstrapUsersFile(path string, defaultJSON []byte) (bool, error)
- func DebugRequestMiddleware() fiber.Handler
- func DefaultBodyLimitMiddleware() fiber.Handler
- func ProjectUUIDMiddleware(repo *database.Repository) fiber.Handler
- func RoleGuard(allowed ...string) fiber.Handler
- func SecurityHeadersMiddleware() fiber.Handler
- type AgentArtifact
- type AgentArtifactListResponse
- type AgentAuditDriverRequest
- type AgentAuditRequest
- type AgentAutopilotRequest
- type AgentBYOK
- type AgentSessionDetail
- type AgentSessionSummary
- type AgentSwarmRequest
- type AgenticScanRequest
- type AgenticScanResponse
- type AgenticScanStatusResponse
- type AppInfoResponse
- type ChatChoice
- type ChatCompletionRequest
- type ChatCompletionResponse
- type ChatMessage
- type ChatUsage
- type ConfigEntryResponse
- type ConfigListResponse
- type ConfigUpdateRequest
- type ConfigUpdateResponse
- type ErrorResponse
- type ExtensionAPIFunction
- type ExtensionDetail
- type ExtensionEditRequest
- type ExtensionInfo
- type FileUser
- type FindingStats
- type HTTPRecordStats
- type Handlers
- func (h *Handlers) Close()
- func (h *Handlers) HandleAgentAudit(c fiber.Ctx) error
- func (h *Handlers) HandleAgentAutopilot(c fiber.Ctx) error
- func (h *Handlers) HandleAgentCancel(c fiber.Ctx) error
- func (h *Handlers) HandleAgentQuery(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSessionArtifact(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSessionArtifacts(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSessionDetail(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSessionList(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSessionLogs(c fiber.Ctx) error
- func (h *Handlers) HandleAgentSwarm(c fiber.Ctx) error
- func (h *Handlers) HandleAgenticScanList(c fiber.Ctx) error
- func (h *Handlers) HandleAgenticScanStatus(c fiber.Ctx) error
- func (h *Handlers) HandleAppInfo(c fiber.Ctx) error
- func (h *Handlers) HandleBurpSiteMapSnapshot(c fiber.Ctx) error
- func (h *Handlers) HandleChatCompletions(c fiber.Ctx) error
- func (h *Handlers) HandleCreateDBRecord(c fiber.Ctx) error
- func (h *Handlers) HandleCreateProject(c fiber.Ctx) error
- func (h *Handlers) HandleDeleteDBRecord(c fiber.Ctx) error
- func (h *Handlers) HandleDeleteOASTInteraction(c fiber.Ctx) error
- func (h *Handlers) HandleDeleteProject(c fiber.Ctx) error
- func (h *Handlers) HandleDeleteRecord(c fiber.Ctx) error
- func (h *Handlers) HandleDeleteScan(c fiber.Ctx) error
- func (h *Handlers) HandleDiagnostics(c fiber.Ctx) error
- func (h *Handlers) HandleEditExtension(c fiber.Ctx) error
- func (h *Handlers) HandleGetConfig(c fiber.Ctx) error
- func (h *Handlers) HandleGetDBRecord(c fiber.Ctx) error
- func (h *Handlers) HandleGetExtension(c fiber.Ctx) error
- func (h *Handlers) HandleGetOASTInteraction(c fiber.Ctx) error
- func (h *Handlers) HandleGetProject(c fiber.Ctx) error
- func (h *Handlers) HandleGetProjectStats(c fiber.Ctx) error
- func (h *Handlers) HandleGetRecord(c fiber.Ctx) error
- func (h *Handlers) HandleGetScan(c fiber.Ctx) error
- func (h *Handlers) HandleGetScanLogs(c fiber.Ctx) error
- func (h *Handlers) HandleGetScope(c fiber.Ctx) error
- func (h *Handlers) HandleHealth(c fiber.Ctx) error
- func (h *Handlers) HandleImport(c fiber.Ctx) error
- func (h *Handlers) HandleIngestHTTP(c fiber.Ctx) error
- func (h *Handlers) HandleListDBRecords(c fiber.Ctx) error
- func (h *Handlers) HandleListDBTableColumns(c fiber.Ctx) error
- func (h *Handlers) HandleListDBTables(c fiber.Ctx) error
- func (h *Handlers) HandleListExtensionAPI(c fiber.Ctx) error
- func (h *Handlers) HandleListExtensions(c fiber.Ctx) error
- func (h *Handlers) HandleListModules(c fiber.Ctx) error
- func (h *Handlers) HandleListOASTInteractions(c fiber.Ctx) error
- func (h *Handlers) HandleListProjects(c fiber.Ctx) error
- func (h *Handlers) HandleListRecords(c fiber.Ctx) error
- func (h *Handlers) HandleListScans(c fiber.Ctx) error
- func (h *Handlers) HandleLogin(c fiber.Ctx) error
- func (h *Handlers) HandleMetrics(c fiber.Ctx) error
- func (h *Handlers) HandlePauseScan(c fiber.Ctx) error
- func (h *Handlers) HandleReady(c fiber.Ctx) error
- func (h *Handlers) HandleResumeScan(c fiber.Ctx) error
- func (h *Handlers) HandleRunScan(c fiber.Ctx) error
- func (h *Handlers) HandleScanAllRecords(c fiber.Ctx) error
- func (h *Handlers) HandleScanRecords(c fiber.Ctx) error
- func (h *Handlers) HandleScanRequest(c fiber.Ctx) error
- func (h *Handlers) HandleScanStatus(c fiber.Ctx) error
- func (h *Handlers) HandleScanURL(c fiber.Ctx) error
- func (h *Handlers) HandleServerInfo(c fiber.Ctx) error
- func (h *Handlers) HandleStats(c fiber.Ctx) error
- func (h *Handlers) HandleStopScan(c fiber.Ctx) error
- func (h *Handlers) HandleStorageDownloadResults(c fiber.Ctx) error
- func (h *Handlers) HandleStorageDownloadSource(c fiber.Ctx) error
- func (h *Handlers) HandleStoragePresign(c fiber.Ctx) error
- func (h *Handlers) HandleStorageUploadSource(c fiber.Ctx) error
- func (h *Handlers) HandleSwaggerSpec(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateAgenticScan(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateConfig(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateDBRecord(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateProject(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateScan(c fiber.Ctx) error
- func (h *Handlers) HandleUpdateScope(c fiber.Ctx) error
- func (h *Handlers) HandleUserInfo(c fiber.Ctx) error
- func (h *Handlers) IsScanRunning() bool
- type HealthResponse
- type ImportRequest
- type ImportResponse
- type IngestHTTPRequest
- type IngestHTTPResponse
- type LoginRequest
- type LoginResponse
- type LoginUser
- type ModuleCount
- type ModuleInfo
- type ModuleStats
- type PaginatedResponse
- type ProjectFindingStats
- type ProjectHTTPRecordStats
- type ProjectRequest
- type ProjectStats
- type ProjectWithStats
- type ResolvedUser
- type RunScanRequest
- type ScanAllRecordsRequest
- type ScanRecordsRequest
- type ScanRequestRequest
- type ScanResponse
- type ScanStatusResponse
- type ScanURLRequest
- type ScopeUpdateResponse
- type Server
- type ServerConfig
- type ServerInfoResponse
- type StatsResponse
- type StoragePresignRequest
- type StoragePresignResponse
- type StorageUploadResponse
- type UpdateFindingStatusRequest
- type UserStore
Constants ¶
const ( ArtifactKindLog = "log" ArtifactKindJSON = "json" ArtifactKindJSONL = "jsonl" ArtifactKindMarkdown = "markdown" ArtifactKindYAML = "yaml" ArtifactKindText = "text" )
Artifact kind tags returned by artifactKind. Clients use these to pick a rendering mode (terminal log, JSON tree, markdown, etc.).
const ( RoleAdmin = "admin" RoleOperator = "operator" RoleViewer = "viewer" )
Role constants for user access control.
const DefaultIngestProxyCADir = "~/.vigolium/ca"
DefaultIngestProxyCADir is the default directory for the ingest-proxy MITM CA (used when ServerConfig.IngestProxyCADir is empty). It is the single source of truth shared with the CLI's --export-ca path so a CA exported out-of-band matches the one the running proxy uses.
const IngestSourceHeader = "X-Vigolium-Source"
IngestSourceHeader lets a client declare which tool the traffic it is pushing came from, so a record ingested by the Caido plugin is distinguishable from one pushed by curl. Mirrors the X-Project-UUID convention: a header rather than a body field, because the seven ingest modes share three save helpers but seven request shapes.
Variables ¶
var ( ErrMissingAuthHeader = errors.New("missing Authorization header") ErrInvalidAuthToken = errors.New("invalid Bearer token") ErrMissingMode = errors.New("'input_mode' field is required") ErrInvalidMode = errors.New("unsupported input mode") ErrMissingContent = errors.New("'content', 'content_base64', or 'http_request_base64' is required") ErrQueueFull = errors.New("queue is full, try again later") ErrServerClosed = errors.New("server is shutting down") ErrDatabaseRequired = errors.New("database is required for this endpoint") ErrScanAlreadyRunning = errors.New("a scan is already running") ErrNoRecordsToScan = errors.New("no records found after scan cursor") ErrAgentNotFound = errors.New("agent run not found") ErrMissingPrompt = errors.New("prompt_template, prompt_file, or prompt is required") ErrMissingTarget = errors.New("'target' field is required") ErrRecordNotFound = errors.New("HTTP record not found") ErrFindingNotFound = errors.New("finding not found") ErrOASTInteractionNotFound = errors.New("OAST interaction not found") ErrMissingURL = errors.New("'url' field is required") ErrMissingRawRequest = errors.New("'raw_request' field is required") ErrInvalidRawRequest = errors.New("failed to parse raw HTTP request") ErrScanNotFound = errors.New("scan not found") ErrMissingRecordUUIDs = errors.New("'record_uuids' field is required") ErrNoValidRecords = errors.New("no valid records found for the provided UUIDs") ErrExtensionNotFound = errors.New("extension not found") ErrForbidden = errors.New("insufficient permissions") ErrInvalidCredentials = errors.New("invalid username or access code") )
Functions ¶
func AuthorHeaderMiddleware ¶
AuthorHeaderMiddleware stamps the `X-Author:` response header, the companion to the `Server:` banner. The value comes from ServerConfig.Author (wired from pkg/cli.Author) rather than a literal here — pkg/server cannot import pkg/cli without an import cycle, and a second copy of the name would drift. registerRoutes skips this middleware entirely when the author is unset, so an empty header is never written.
func BearerAuth ¶
BearerAuth returns fiber middleware that validates Bearer tokens and resolves user identity. Checks the UserStore first (file-based users), then falls back to legacy API keys (admin role). Skips authentication for public endpoints: /, /health, /ready, /swagger/*, /metrics.
func BootstrapUsersFile ¶
BootstrapUsersFile creates the users file from the embedded default template if it does not already exist. Each user with an empty access_code gets a freshly generated one. Returns true if a new file was created.
func DebugRequestMiddleware ¶
DebugRequestMiddleware logs the raw request body, URL/query parameters, and headers for every incoming request when --debug is enabled.
Sensitive headers and BYOK body fields are scrubbed before the line is emitted — see redact.go for the precise lists. JSON-shaped bodies are parsed and re-serialized; non-JSON or malformed bodies are summarized rather than logged verbatim so a binary upload doesn't tank the log.
func DefaultBodyLimitMiddleware ¶
DefaultBodyLimitMiddleware rejects request bodies larger than defaultBodyLimit for routes that aren't in bodyLimitExemptPaths.
With StreamRequestBody enabled (see fiber.Config) the declared-Content-Length check rejects an oversized body before it is read into memory, so a normal JSON route no longer buffers up to the framework's 512 MB ceiling just to bounce it. A chunked or otherwise undeclared body has no length to check, and there the naive `len(c.Body()) > limit` is the problem rather than the fix: c.Body() drains the stream first and asks afterwards, and the only ceiling on that drain is the framework BodyLimit — so a sender who omits Content-Length gets to grow the server's heap by 512 MB per request on a route whose limit is 4 MB, and a handful of concurrent senders can exhaust memory on requests that were always going to be rejected.
So the undeclared case is read explicitly, through a reader capped one byte past the limit: at most limit+1 bytes are ever allocated, and crossing the threshold is detectable without having consumed what follows.
func ProjectUUIDMiddleware ¶
func ProjectUUIDMiddleware(repo *database.Repository) fiber.Handler
ProjectUUIDMiddleware extracts the project UUID from the X-Project-UUID request header and stores it in Fiber locals. Falls back to DefaultProjectUUID when the header is empty.
When repo is non-nil and the supplied UUID does not exist in the database, the middleware lazily creates a stub project row so callers (including UIs after a scanner DB reset) can keep working with the UUID stored client-side. Auto-creation is skipped for public/utility endpoints and for the default project UUID, which is seeded separately.
func RoleGuard ¶
RoleGuard returns middleware that rejects requests from users whose role is not in the allowed set. Must be applied after BearerAuth. When no auth user is present (--no-auth mode), requests are allowed through.
func SecurityHeadersMiddleware ¶
SecurityHeadersMiddleware adds security headers to all responses.
Types ¶
type AgentArtifact ¶
type AgentArtifact struct {
Name string `json:"name"` // path relative to session_dir
Size int64 `json:"size"` // bytes
ModifiedAt time.Time `json:"modified_at"` // mtime
Kind string `json:"kind"` // "log", "json", "markdown", "yaml", "jsonl", "text", "binary"
}
AgentArtifact is one file under an agent session directory.
type AgentArtifactListResponse ¶
type AgentArtifactListResponse struct {
AgenticScanUUID string `json:"agentic_scan_uuid"`
SessionDir string `json:"session_dir"`
Artifacts []AgentArtifact `json:"artifacts"`
Truncated bool `json:"truncated,omitempty"` // true when the walk hit the file cap
}
AgentArtifactListResponse lists files under an agent session directory.
type AgentAuditDriverRequest ¶
type AgentAuditDriverRequest struct {
Source string `json:"source,omitempty"` // local path, git URL, gs:// archive, or local archive (required)
Target string `json:"target,omitempty"` // optional target URL — stored on the run row for cross-referencing scans
Intensity string `json:"intensity,omitempty"` // quick | balanced (default) | deep — bundles mode + timeout + commit_depth
Mode string `json:"mode,omitempty"` // explicit audit mode: lite, balanced, scan, deep, mock, revisit, reinvest, confirm, merge, diff, status (overrides intensity)
Modes []string `json:"modes,omitempty"` // mode chain run back-to-back via audit's native --modes (e.g. ["deep","refresh","confirm"]); overrides mode/intensity, stops on first non-complete
Platform string `json:"platform,omitempty"` // claude | codex (default: from settings, then claude)
Agent string `json:"agent,omitempty"` // alias for platform — accepted for parity with the CLI flag
Timeout string `json:"timeout,omitempty"` // Go duration string; overrides intensity preset (quick=1h, balanced=6h, deep=12h)
Diff string `json:"diff,omitempty"` // focus on changed code: PR URL, git ref range, or HEAD~N
LastCommits int `json:"last_commits,omitempty"` // focus on last N commits (shorthand for diff HEAD~N)
CommitDepth int `json:"commit_depth,omitempty"` // git clone --depth when source is a git URL; overrides intensity preset (quick/balanced=1, deep=0)
Files []string `json:"files,omitempty"` // specific files to focus on
Stream bool `json:"stream,omitempty"` // enable SSE streaming of agent output
UploadResults bool `json:"upload_results,omitempty"` // upload session bundle to cloud storage on completion
ProjectUUID string `json:"project_uuid,omitempty"` // project UUID for data scoping
ScanUUID string `json:"scan_uuid,omitempty"` // optional scan UUID
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file, oauth_cred_json)
// are accepted at the top level of the request body via JSON field
// promotion. See AgentBYOK doc for resolution semantics.
AgentBYOK
}
AgentAuditDriverRequest is the request body for POST /api/agent/run/audit. Mirrors the autopilot request shape for the fields audit actually consumes (source, intensity/mode, platform, timeout, diff context, scoping, streaming).
func (AgentAuditDriverRequest) EffectivePlatform ¶
func (r AgentAuditDriverRequest) EffectivePlatform() string
EffectivePlatform resolves the platform field, accepting the legacy `agent` alias used by the CLI flag (`--agent claude|codex`).
type AgentAuditRequest ¶
type AgentAuditRequest struct {
Source string `json:"source,omitempty"` // local path, git URL, gs:// archive, or local archive (required)
Target string `json:"target,omitempty"` // optional target URL — stored on the run row for cross-referencing scans
Intensity string `json:"intensity,omitempty"` // quick | balanced (default) | deep — bundles mode + timeout + commit_depth
Mode string `json:"mode,omitempty"` // explicit audit mode (overrides intensity). With driver=auto or driver=both, restricted to: lite, balanced, deep, revisit, confirm, merge. With driver=piolium adds: diff, longshot, status, smoke. With driver=audit adds: reinvest, diff, status, mock.
Modes []string `json:"modes,omitempty"` // mode chain run back-to-back (e.g. ["deep","refresh","confirm"]); overrides mode/intensity. audit runs it natively; piolium chains via sequential runs collapsed into one row; with driver=auto/both, modes a driver can't run are skipped on that driver's leg.
Timeout string `json:"timeout,omitempty"` // Go duration string; overrides intensity preset (quick=1h, balanced=6h, deep=12h)
Diff string `json:"diff,omitempty"` // focus on changed code: PR URL, git ref range, or HEAD~N
LastCommits int `json:"last_commits,omitempty"` // focus on last N commits (shorthand for diff HEAD~N)
CommitDepth int `json:"commit_depth,omitempty"` // git clone --depth when source is a git URL; overrides intensity preset (quick/balanced=1, deep=0)
Files []string `json:"files,omitempty"` // specific files to focus on
Stream bool `json:"stream,omitempty"` // enable SSE streaming of agent output. With driver=auto/both, events are tagged with a "driver" field
UploadResults bool `json:"upload_results,omitempty"` // upload session bundle to cloud storage on completion
ProjectUUID string `json:"project_uuid,omitempty"` // project UUID for data scoping
ScanUUID string `json:"scan_uuid,omitempty"` // optional scan UUID
// Driver picks which audit harnesses participate. One of:
// "auto" — audit first; piolium runs only as a fallback if
// audit fails (a clean audit run finishes the audit
// and piolium is never started). Default when empty.
// "both" — sequential audit-then-piolium under one parent
// AgenticScan, run unconditionally
// "audit" — audit only (equivalent to /api/agent/run/audit)
// "piolium" — piolium only
// "auto" and "both" run under one parent AgenticScan with per-driver
// child rows, post-pass findings dedup, and multiplexed SSE.
// Defaults to "auto" when empty.
Driver string `json:"driver,omitempty"`
// NoDedup skips the post-pass project-wide findings dedup that runs
// after the audit completes. Only meaningful for driver=auto/both,
// since single-driver runs already INSERT-time-dedup by finding_hash.
NoDedup bool `json:"no_dedup,omitempty"`
// KeepRaw maps to vigolium-audit's `--keep-raw`: opt out of the
// deep/confirm auto-prune so raw scanner output, draft findings, and
// intermediate workspaces stay under <source>/vigolium-results/ (and
// the synced session copy) for manual review. Audit-only — ignored on
// the piolium leg of driver=auto/both/piolium runs.
KeepRaw bool `json:"keep_raw,omitempty"`
// Agent picks the audit platform when audit participates. Accepts
// claude (default) or codex. Ignored when driver=piolium.
Agent string `json:"agent,omitempty"`
// Pi provider/model overrides, forwarded as `pi --provider X --model Y`.
// Empty values fall back to whatever the user has configured in
// ~/.pi/agent/settings.json. Ignored when driver=audit.
PiProvider string `json:"pi_provider,omitempty"`
PiModel string `json:"pi_model,omitempty"`
// Piolium passthrough flags (`--plm-*`). Empty/zero values are dropped
// so piolium's own defaults still apply. Ignored when driver=audit.
PlmScanLimit int `json:"plm_scan_limit,omitempty"` // cap commit-history scan to N commits
PlmScanSince string `json:"plm_scan_since,omitempty"` // git --since window (e.g. "60 days ago")
PlmPhaseRetries int `json:"plm_phase_retries,omitempty"` // per-phase retry count
PlmCommandRetries int `json:"plm_command_retries,omitempty"` // per-command retry count
PlmLongshotLimit int `json:"plm_longshot_limit,omitempty"` // max files in longshot mode
PlmLongshotTimeout int `json:"plm_longshot_timeout,omitempty"` // per-file kill timer in ms (longshot)
PlmLongshotLangs string `json:"plm_longshot_langs,omitempty"` // comma-separated language allowlist
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file, oauth_cred_json)
// are accepted at the top level of the request body via JSON field
// promotion. The audit dispatcher applies these to whichever driver(s)
// actually run: audit receives them as --api-key / --oauth-token /
// --oauth-cred-file flags; piolium receives them as env vars on the pi
// subprocess (and, for codex cred files, a temporarily-staged auth.json
// under the configured pi-agent-dir, restored on completion). See
// AgentBYOK doc for full semantics.
AgentBYOK
// AuditDriverAuth, when set, OVERRIDES the top-level AgentBYOK for the
// audit driver only. Used with driver=auto/both to give each driver
// its own identity (e.g. one tenant's claude OAuth for the audit side,
// another tenant's codex cred file for piolium). When unset, audit
// inherits the top-level AgentBYOK. Ignored when driver=piolium.
AuditDriverAuth *AgentBYOK `json:"audit_auth,omitempty"`
// PioliumAuth, when set, OVERRIDES the top-level AgentBYOK for the
// piolium driver only. Symmetric to AuditDriverAuth. Ignored when
// driver=audit.
PioliumAuth *AgentBYOK `json:"piolium_auth,omitempty"`
}
AgentAuditRequest is the request body for POST /api/agent/run/audit.
Mirrors the `vigolium agent audit` CLI: dispatches audit and/or piolium against a source tree (local path, git URL, gs:// archive, or local archive) under one AgenticScan. When driver=auto (default), audit runs first and piolium only runs as a fallback if audit fails — a clean audit run finishes the audit and piolium is never started. When driver=both, both drivers run sequentially (audit first, then piolium) unconditionally. Multi-driver runs use per-driver child AgenticScan rows. Same /agent/status, /agent/sessions/:id/logs, and /agent/sessions/:id/artifacts shape as the single-driver endpoints.
Optional fields default to the same values as their CLI counterparts; in particular, the `pi_*` and `plm_*` knobs only fire when explicitly set.
type AgentAutopilotRequest ¶
type AgentAutopilotRequest struct {
Prompt string `json:"prompt,omitempty"` // natural language scan prompt (parsed into target/source/focus when explicit fields are empty)
Intensity string `json:"intensity,omitempty"` // scan intensity preset: quick, balanced (default), deep
Target string `json:"target,omitempty"` // target URL (derived from input if not set)
Input string `json:"input,omitempty"` // raw input (curl, raw HTTP, Burp XML, URL) — target extracted automatically
Agent string `json:"agent,omitempty"` // agent backend name
SourcePath string `json:"source,omitempty"` // path to application source code
Files []string `json:"files,omitempty"` // specific files to include
Focus string `json:"focus,omitempty"` // focus area hint
Instruction string `json:"instruction,omitempty"` // custom instruction appended to the prompt
Timeout string `json:"timeout,omitempty"` // Go duration string, default "6h"
MaxCommands int `json:"max_commands,omitempty"` // max CLI commands, default 100
DryRun bool `json:"dry_run,omitempty"` // render prompt without executing
Stream bool `json:"stream,omitempty"` // enable SSE streaming
ScanUUID string `json:"scan_uuid,omitempty"` // optional scan UUID
ProjectUUID string `json:"project_uuid,omitempty"` // project UUID for data scoping
// Deprecated: use NoAudit + AuditDriverMode instead. Kept for backward
// compatibility with older API clients; "off" maps to NoAudit=true and
// any other value (e.g. "deep") maps to AuditDriverMode. Slated for removal.
Audit string `json:"audit,omitempty"` // legacy values: "lite", "balanced", "deep", "off"
NoAudit bool `json:"no_audit,omitempty"` // disable automatic vigolium-audit (enabled by default when source is set)
AuditDriverMode string `json:"audit_mode,omitempty"` // audit mode: "lite" (default), "balanced", "deep"
Diff string `json:"diff,omitempty"` // focus on changed code: PR URL, git ref range, or HEAD~N
LastCommits int `json:"last_commits,omitempty"` // focus on last N commits (shorthand for diff HEAD~N)
Browser bool `json:"browser,omitempty"` // explicitly enable browser tooling
Credentials string `json:"credentials,omitempty"` // compact credential hint for preflight auth setup
CredentialSets []agent.IntentCredentialSet `json:"credential_sets,omitempty"` // structured roles/accounts for preflight auth setup
AuthRequired bool `json:"auth_required,omitempty"` // authenticate before scan
RequiresBrowser bool `json:"requires_browser,omitempty"` // browser is required for login/auth setup
BrowserStartURL string `json:"browser_start_url,omitempty"` // explicit login/start URL for browser-based flows
FocusRoutes []string `json:"focus_routes,omitempty"` // protected/browser focus routes
// Piolium audit mode (Pi runtime). Empty triggers server-side auto-pick:
// when pi+piolium are installed, the server runs piolium instead of
// audit. Set explicitly to force piolium; pair with audit:"off" to
// keep both off, or with an audit mode to keep audit (auto-pick is
// suppressed once either flag is set).
Piolium string `json:"piolium,omitempty"`
// Triage, when true, runs an AI triage pass over the findings after the
// scan completes — classifying each as confirmed or false positive and
// writing the verdict back to finding status. Pure classification (no
// native rescan).
Triage bool `json:"triage,omitempty"`
// NoPreflightDiscovery disables the pre-flight discovery + OpenAPI/Swagger
// ingestion pass that seeds http_records before the operator agent
// starts. Default false (pre-flight on). Set true to skip — useful when
// the caller has already seeded the project via --input or a prior scan.
NoPreflightDiscovery bool `json:"no_preflight_discovery,omitempty"`
// NoPostHaltVerify disables the post-halt coverage verification loop —
// the agent's halt_scan is accepted as final regardless of whether a
// follow-up discovery probe would surface new routes. Default false
// (verification on). Cap the cost via PostHaltGapThreshold rather than
// disabling entirely when possible.
NoPostHaltVerify bool `json:"no_post_halt_verify,omitempty"`
// PostHaltGapThreshold sets the minimum number of new routes the
// post-halt probe must turn up before the agent is re-entered. 0 falls
// back to the autopilot's built-in default (5).
PostHaltGapThreshold int `json:"post_halt_gap_threshold,omitempty"`
// Upload results to cloud storage after scan completion
UploadResults bool `json:"upload_results,omitempty"`
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file, oauth_cred_json)
// are accepted at the top level of the request body. The in-process
// olium engine for this run is built with these overlaid onto the
// server-wide agent.olium.* defaults; the background audit (when
// enabled via AuditDriverMode/Piolium) inherits the same overrides.
AgentBYOK
}
AgentAutopilotRequest is the request body for POST /api/agent/run/autopilot.
func (AgentAutopilotRequest) ResolvedAuditDriverMode ¶
func (r AgentAutopilotRequest) ResolvedAuditDriverMode() string
ResolvedAuditDriverMode returns the effective audit mode, handling backward compatibility with the legacy Audit field.
func (AgentAutopilotRequest) ResolvedNoAudit ¶
func (r AgentAutopilotRequest) ResolvedNoAudit() bool
ResolvedNoAudit returns true when audit should be disabled, handling backward compatibility with the legacy Audit field.
type AgentBYOK ¶
type AgentBYOK struct {
APIKey string `json:"api_key,omitempty"`
OAuthToken string `json:"oauth_token,omitempty"`
OAuthCredFile string `json:"oauth_cred_file,omitempty"`
OAuthCredJSON string `json:"oauth_cred_json,omitempty"`
}
AgentBYOK is the shared shape of "bring your own key" credentials sent on agent endpoints. Embedded in every request type that runs an agent (audit/audit subprocess drivers, autopilot/swarm/query in-process olium) so callers get a uniform field surface regardless of which endpoint they target.
Field semantics (mutually exclusive — at most one of APIKey / OAuthToken / OAuthCredFile / OAuthCredJSON may be non-empty):
- APIKey — Anthropic or OpenAI API key. Routed to the right env / x-api-key header by the receiving driver.
- OAuthToken — Claude Code OAuth token (`sk-ant-oat01-…` from `claude setup-token`). Claude-only.
- OAuthCredFile — server-side path to a Codex auth.json. DEPRECATED: server-supplied paths let any operator point the audit at any readable file. New integrations should send the contents inline via OAuthCredJSON.
- OAuthCredJSON — raw contents of a Codex auth.json. Staged by the server to a per-request 0600 temp file, used for one run, then deleted.
Values are treated as literals — unlike the CLI flags, REST does NOT honor $ENV / @path indirection. Doing so would let a network caller probe the server's environment or filesystem.
type AgentSessionDetail ¶
type AgentSessionDetail struct {
AgentSessionSummary
InputRaw string `json:"input_raw,omitempty"`
ModuleNames []string `json:"module_names,omitempty"`
SessionID string `json:"session_id,omitempty"`
PromptSent string `json:"prompt_sent,omitempty"`
AgentRawOutput string `json:"agent_raw_output,omitempty"`
AttackPlan string `json:"attack_plan,omitempty"`
TriageResult string `json:"triage_result,omitempty"`
ResultJSON string `json:"result_json,omitempty"`
ChildRuns []*AgentSessionDetail `json:"child_runs,omitempty"`
}
AgentSessionDetail is the full representation of an agent run including debug fields.
type AgentSessionSummary ¶
type AgentSessionSummary struct {
UUID string `json:"uuid"`
Mode string `json:"mode"`
Status string `json:"status"`
AgentName string `json:"agent_name,omitempty"`
TemplateID string `json:"template_id,omitempty"`
TargetURL string `json:"target_url,omitempty"`
SourcePath string `json:"source_path,omitempty"`
SessionDir string `json:"session_dir,omitempty"`
VulnType string `json:"vuln_type,omitempty"`
InputType string `json:"input_type,omitempty"`
ParentAgenticScanUUID string `json:"parent_agentic_scan_uuid,omitempty"`
CurrentPhase string `json:"current_phase,omitempty"`
PhasesRun []string `json:"phases_run,omitempty"`
FindingCount int `json:"finding_count,omitempty"`
RecordCount int `json:"record_count,omitempty"`
SavedCount int `json:"saved_count,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
DurationMs int64 `json:"duration_ms,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
StorageURL string `json:"storage_url,omitempty"`
}
AgentSessionSummary is a lightweight representation of an agent run for list responses.
type AgentSwarmRequest ¶
type AgentSwarmRequest struct {
// Natural language prompt (parsed into structured fields when explicit fields are empty)
Prompt string `json:"prompt,omitempty"`
// Scan intensity preset: quick, balanced (default), deep
Intensity string `json:"intensity,omitempty"`
// Inputs
Input string `json:"input,omitempty"` // single input (URL, curl, raw HTTP, Burp XML, record UUID)
Inputs []string `json:"inputs,omitempty"` // multiple inputs (for auth flows)
HTTPRequestBase64 string `json:"http_request_base64,omitempty"` // base64-encoded raw HTTP request (ingested into DB, UUID used as input)
HTTPResponseBase64 string `json:"http_response_base64,omitempty"` // base64-encoded raw HTTP response (attached to the request above)
URL string `json:"url,omitempty"` // optional URL hint for parsing the base64 request
// Source analysis
SourcePath string `json:"source,omitempty"` // path to source code for route discovery (triggers source analysis phase)
Files []string `json:"files,omitempty"` // specific source files to include (relative to source)
SourceAnalysisOnly bool `json:"source_analysis_only,omitempty"` // run only source analysis phase and exit
// Scanning parameters
VulnType string `json:"vuln_type,omitempty"` // vulnerability type focus
Focus string `json:"focus,omitempty"` // broad focus area hint (e.g. "API injection", "auth bypass")
Instruction string `json:"instruction,omitempty"` // custom instruction appended to agent prompts
ModuleNames []string `json:"module_names,omitempty"` // explicit module IDs
OnlyPhase string `json:"only_phase,omitempty"` // isolate a single phase
SkipPhases []string `json:"skip_phases,omitempty"` // skip specific phases
StartFrom string `json:"start_from,omitempty"` // resume from a specific phase
MaxIterations int `json:"max_iterations,omitempty"` // max triage-rescan rounds (default 3)
Discover bool `json:"discover,omitempty"` // run discovery+spidering before master agent planning
CodeAudit bool `json:"code_audit,omitempty"` // enable AI security code audit phase
Triage bool `json:"triage,omitempty"` // enable AI triage and rescan phases (disabled by default)
Profile string `json:"profile,omitempty"` // scanning profile name (e.g. "light", "thorough")
// Agent selection
Agent string `json:"agent,omitempty"` // agent backend name
// Auth/browser intent
Browser bool `json:"browser,omitempty"` // explicitly enable browser tooling
Auth bool `json:"auth,omitempty"` // explicitly run browser auth phase
Credentials string `json:"credentials,omitempty"` // compact credential hint
CredentialSets []agent.IntentCredentialSet `json:"credential_sets,omitempty"` // structured roles/accounts
AuthRequired bool `json:"auth_required,omitempty"` // authenticate before scan
RequiresBrowser bool `json:"requires_browser,omitempty"` // browser is required for login/auth setup
BrowserStartURL string `json:"browser_start_url,omitempty"` // explicit login/start URL
FocusRoutes []string `json:"focus_routes,omitempty"` // protected/browser focus routes
// Concurrency tuning
BatchConcurrency int `json:"batch_concurrency,omitempty"` // max parallel master agent batches (0 = auto)
MaxMasterRetries int `json:"max_master_retries,omitempty"` // max master agent retries on parse failure (0 = default 3)
SAMaxConcurrency int `json:"sa_max_concurrency,omitempty"` // max parallel source analysis sub-agents (0 = default 3)
MaxPlanRecords int `json:"max_plan_records,omitempty"` // max records sent to plan agent (0 = use intensity preset, which picks 10/25/50 for quick/balanced/deep)
MasterBatchSize int `json:"master_batch_size,omitempty"` // max records per master agent batch (0 = default 5)
ProbeConcurrency int `json:"probe_concurrency,omitempty"` // max parallel probe requests (0 = default 10)
ProbeTimeout string `json:"probe_timeout,omitempty"` // per-request probe timeout as Go duration e.g. "10s" (0 = default 10s)
MaxProbeBodySize int `json:"max_probe_body,omitempty"` // max response body size in bytes during probing (0 = default 2MB)
// Output control
DryRun bool `json:"dry_run,omitempty"` // render prompts without executing
ShowPrompt bool `json:"show_prompt,omitempty"` // include rendered prompts in output
Stream bool `json:"stream,omitempty"` // enable SSE streaming
Timeout string `json:"timeout,omitempty"` // Go duration string
// Project/scan scoping
ProjectUUID string `json:"project_uuid,omitempty"` // optional project UUID
ScanUUID string `json:"scan_uuid,omitempty"` // optional scan UUID
// Background vigolium-audit
Audit string `json:"audit,omitempty"` // run background vigolium-audit: "lite" (3-phase), "balanced" (6-phase), "deep" (10-phase), "off" to disable
// Background piolium audit (Pi runtime). Empty triggers server-side
// auto-pick when audit is also empty: piolium runs when pi+piolium
// are installed, otherwise nothing. Set explicitly to force piolium.
Piolium string `json:"piolium,omitempty"`
// Diff context
Diff string `json:"diff,omitempty"` // focus on changed code: PR URL, git ref range, or HEAD~N
LastCommits int `json:"last_commits,omitempty"` // focus on last N commits (shorthand for diff HEAD~N)
// Upload results to cloud storage after scan completion
UploadResults bool `json:"upload_results,omitempty"`
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file, oauth_cred_json)
// are accepted at the top level. Master / triage / source-analysis
// agents all run against the in-process olium engine; when set, the
// engine for this run is built with these overlaid onto the server-wide
// agent.olium.* defaults.
AgentBYOK
}
AgentSwarmRequest is the request body for POST /api/agent/run/swarm.
func (AgentSwarmRequest) EffectiveInputs ¶
func (r AgentSwarmRequest) EffectiveInputs() []string
EffectiveInputs returns all inputs as a slice, merging Input and Inputs.
func (AgentSwarmRequest) ResolvedAuditDriverMode ¶
func (r AgentSwarmRequest) ResolvedAuditDriverMode() string
ResolvedAuditDriverMode returns the effective audit mode. Returns empty string when audit is disabled.
func (AgentSwarmRequest) ResolvedNoAudit ¶
func (r AgentSwarmRequest) ResolvedNoAudit() bool
ResolvedNoAudit returns true when audit should be disabled. Swarm uses opt-in audit: empty string means disabled.
func (*AgentSwarmRequest) UnmarshalJSON ¶
func (r *AgentSwarmRequest) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom unmarshaling for AgentSwarmRequest to support the legacy "source_path" JSON key as a backward-compatible alias for "source".
type AgenticScanRequest ¶
type AgenticScanRequest struct {
Agent string `json:"agent,omitempty"`
PromptTemplate string `json:"prompt_template,omitempty"`
PromptFile string `json:"prompt_file,omitempty"`
Prompt string `json:"prompt,omitempty"`
SourcePath string `json:"source,omitempty"` // path to source code
Files []string `json:"files,omitempty"`
Append string `json:"append,omitempty"`
Instruction string `json:"instruction,omitempty"` // custom instruction appended to the prompt
Source string `json:"source_label,omitempty"`
ScanUUID string `json:"scan_uuid,omitempty"`
ProjectUUID string `json:"project_uuid,omitempty"` // project UUID for storage scoping (falls back to X-Project-UUID header)
Stream bool `json:"stream,omitempty"`
UploadResults bool `json:"upload_results,omitempty"` // upload session bundle to cloud storage on completion
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file, oauth_cred_json)
// are accepted at the top level. When set, the in-process olium engine
// for this request is built from a per-request OliumConfig overlay rather
// than the server-wide agent.olium.* defaults.
AgentBYOK
}
AgenticScanRequest is the request body for POST /api/agent/run/query.
type AgenticScanResponse ¶
type AgenticScanResponse struct {
AgenticScanUUID string `json:"agentic_scan_uuid"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
}
AgenticScanResponse is the response for POST /api/agent/run/*.
type AgenticScanStatusResponse ¶
type AgenticScanStatusResponse struct {
AgenticScanUUID string `json:"agentic_scan_uuid"`
ProjectUUID string `json:"project_uuid,omitempty"` // owning project; scopes status/list/cancel to X-Project-UUID
Mode string `json:"mode"` // "query", "autopilot", "pipeline"
Status string `json:"status"` // "running", "completed", "failed"
AgentName string `json:"agent_name,omitempty"`
TemplateID string `json:"template_id,omitempty"`
FindingCount int `json:"finding_count,omitempty"`
RecordCount int `json:"record_count,omitempty"`
SavedCount int `json:"saved_count,omitempty"`
Error string `json:"error,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
Result *agent.Result `json:"result,omitempty"`
StorageURL string `json:"storage_url,omitempty"`
// Phase progress fields
CurrentPhase string `json:"current_phase,omitempty"`
PhasesRun []string `json:"phases_run,omitempty"`
// Swarm/pipeline result
SwarmResult *agent.SwarmResult `json:"swarm_result,omitempty"`
}
AgenticScanStatusResponse is the response for GET /api/agent/status/:id and GET /api/agent/status/list.
type AppInfoResponse ¶
type AppInfoResponse struct {
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author"`
Docs string `json:"docs"`
LicenseSPDX string `json:"license_spdx"`
Source string `json:"source"`
BuildTime string `json:"build_time,omitempty"`
Commit string `json:"commit,omitempty"`
}
AppInfoResponse is the response for GET /api/info.
type ChatChoice ¶
type ChatChoice struct {
Index int `json:"index"`
Message ChatMessage `json:"message"`
FinishReason string `json:"finish_reason"`
}
ChatChoice represents a single completion choice.
type ChatCompletionRequest ¶
type ChatCompletionRequest struct {
Model string `json:"model"`
Messages []ChatMessage `json:"messages"`
// AgentBYOK fields (api_key, oauth_token, oauth_cred_file,
// oauth_cred_json) are accepted at the top level. In no-auth server
// mode, an `Authorization: Bearer <key>` header is also promoted into
// AgentBYOK.APIKey for OpenAI-SDK compatibility.
AgentBYOK
}
ChatCompletionRequest is an OpenAI-compatible chat completion request.
type ChatCompletionResponse ¶
type ChatCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []ChatChoice `json:"choices"`
Usage *ChatUsage `json:"usage,omitempty"`
}
ChatCompletionResponse is an OpenAI-compatible chat completion response.
type ChatMessage ¶
ChatMessage represents a single message in a chat completion request/response.
type ChatUsage ¶
type ChatUsage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
}
ChatUsage reports token usage for a chat completion.
type ConfigEntryResponse ¶
type ConfigEntryResponse struct {
Key string `json:"key"`
Value string `json:"value"`
Sensitive bool `json:"sensitive,omitempty"`
}
ConfigEntryResponse is a single config entry in API responses.
type ConfigListResponse ¶
type ConfigListResponse struct {
Entries []ConfigEntryResponse `json:"entries"`
Total int `json:"total"`
}
ConfigListResponse is the response for GET /api/config.
type ConfigUpdateRequest ¶
ConfigUpdateRequest is the request body for POST /api/config. Keys are dot-notation paths, values are string representations.
type ConfigUpdateResponse ¶
type ConfigUpdateResponse struct {
Message string `json:"message"`
Updated []ConfigEntryResponse `json:"updated"`
Errors []string `json:"errors,omitempty"`
}
ConfigUpdateResponse is the response for POST /api/config.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
Code int `json:"code,omitempty"`
Details string `json:"details,omitempty"`
}
ErrorResponse is returned for error conditions.
type ExtensionAPIFunction ¶
type ExtensionAPIFunction struct {
Category string `json:"category"`
Namespace string `json:"namespace"`
Name string `json:"name"`
FullName string `json:"full_name"`
Signature string `json:"signature"`
Returns string `json:"returns"`
Description string `json:"description"`
Example string `json:"example,omitempty"`
}
ExtensionAPIFunction is a single JS utility function entry.
type ExtensionDetail ¶
type ExtensionDetail struct {
ExtensionInfo
RawContent string `json:"raw_content"`
}
ExtensionDetail is the full extension response including raw file content, returned by GET /api/extensions/:name.
type ExtensionEditRequest ¶
type ExtensionEditRequest struct {
Content string `json:"content"`
}
ExtensionEditRequest is the request body for PUT /api/extensions/:name.
type ExtensionInfo ¶
type ExtensionInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Language string `json:"language"` // "js" or "yaml"
Type string `json:"type"` // "active", "passive", "pre_hook", "post_hook"
Severity string `json:"severity,omitempty"`
Confidence string `json:"confidence,omitempty"` // tentative, firm, certain
ScanTypes []string `json:"scan_types,omitempty"`
Tags []string `json:"tags,omitempty"`
Scope string `json:"scope,omitempty"`
Description string `json:"description,omitempty"`
ConfirmationCriteria string `json:"confirmation_criteria,omitempty"`
File string `json:"file"`
FileName string `json:"file_name"`
}
ExtensionInfo is the metadata summary of a loaded extension, returned in list responses.
type FileUser ¶
type FileUser struct {
Name string `json:"name"`
Email string `json:"email"`
AccessCode string `json:"access_code"`
Role string `json:"role"`
}
FileUser represents a single entry in the users JSON file.
func LoadUsersFile ¶
LoadUsersFile reads and parses a users JSON file from the given path. Returns nil, nil if the file does not exist or is empty (graceful fallback to legacy auth).
type FindingStats ¶
type FindingStats struct {
Total int64 `json:"total"`
BySeverity map[string]int64 `json:"by_severity"`
}
FindingStats holds finding counts.
type HTTPRecordStats ¶
type HTTPRecordStats struct {
Total int64 `json:"total"`
}
HTTPRecordStats holds HTTP record counts.
type Handlers ¶
type Handlers struct {
// contains filtered or unexported fields
}
Handlers holds the HTTP handlers and their dependencies.
func NewHandlers ¶
func NewHandlers(q queue.Queue, db *database.DB, repo *database.Repository, rw *database.RecordWriter, cfg ServerConfig, settings *config.Settings, httpRequester *http.Requester, svc *services.Services) *Handlers
NewHandlers creates a new Handlers instance. Starts a background goroutine to clean up old agent run records from the database.
func (*Handlers) HandleAgentAudit ¶
HandleAgentAudit handles POST /api/agent/run/audit — launches one or both audit drivers (audit and piolium) against a source tree.
`driver` selects which harnesses participate; "both" (default) runs them sequentially under one parent AgenticScan with per-driver child rows, multiplexed SSE events tagged by driver, and a post-pass project-wide findings dedup. With "both", `mode` is restricted to the shared set — driver-specific modes require an explicit single-driver value.
func (*Handlers) HandleAgentAutopilot ¶
HandleAgentAutopilot handles POST /api/agent/run/autopilot — launches an autonomous AI scanning session.
func (*Handlers) HandleAgentCancel ¶
HandleAgentCancel handles POST /api/agent/scans/:uuid/cancel — aborts an in-flight agent run (autopilot/swarm/query/audit). It cancels the run's context, which unwinds the run and lets its finalization record the terminal "cancelled" status. Returns 404 when no run with that UUID is currently running in this process (already finished, never started, or unknown).
func (*Handlers) HandleAgentQuery ¶
HandleAgentQuery handles POST /api/agent/run/query — triggers a single-shot AI agent run. When "stream":true, the response is an SSE stream; otherwise it returns 202 async.
func (*Handlers) HandleAgentSessionArtifact ¶
HandleAgentSessionArtifact serves a single file from an agent session directory. The file path is captured by the wildcard route segment and is resolved within the session_dir; any attempt to escape via "..", absolute paths, or symlinks pointing outside the session_dir is rejected with 400.
When the file exists and is small enough, its bytes are streamed back with a content-type derived from the extension. Use ?max_bytes=N to override the default 10 MiB cap (hard cap: 100 MiB).
func (*Handlers) HandleAgentSessionArtifacts ¶
HandleAgentSessionArtifacts lists files inside an agent session directory. The walk is recursive but capped at maxArtifactListEntries; the response flags `truncated: true` when the cap is hit. Names are returned as paths relative to the session_dir so they can be passed back to HandleAgentSessionArtifact unchanged.
func (*Handlers) HandleAgentSessionDetail ¶
HandleAgentSessionDetail returns full details for a single agent session.
func (*Handlers) HandleAgentSessionList ¶
HandleAgentSessionList returns a paginated list of agent sessions from the database.
func (*Handlers) HandleAgentSessionLogs ¶
HandleAgentSessionLogs serves the raw run.log console stream for an agent session. With Accept: text/event-stream it tails the file as SSE until the run reaches a terminal status; otherwise it returns the full file as text/plain. ANSI colors are preserved by default so clients that render a terminal (xterm.js, etc.) see what the CLI user would see; pass ?strip=1 to get plain text with escape sequences removed.
func (*Handlers) HandleAgentSwarm ¶
HandleAgentSwarm handles POST /api/agent/run/swarm — launches an AI-guided targeted swarm.
func (*Handlers) HandleAgenticScanList ¶
HandleAgenticScanList handles GET /api/agent/status/list — returns all agent run statuses. Returns from database for historical runs, merged with in-memory status for active runs.
func (*Handlers) HandleAgenticScanStatus ¶
HandleAgenticScanStatus handles GET /api/agent/status/:id — returns status of a specific agent run.
func (*Handlers) HandleAppInfo ¶
HandleAppInfo handles GET /api/info — returns basic app info.
func (*Handlers) HandleBurpSiteMapSnapshot ¶
func (*Handlers) HandleChatCompletions ¶
HandleChatCompletions handles POST /api/agent/chat/completions — OpenAI-compatible chat endpoint.
BYOK is accepted via two channels for OpenAI-client compatibility:
- Standard body fields (api_key / oauth_token / oauth_cred_file / oauth_cred_json) like every other /agent/run/* endpoint.
- An `Authorization: Bearer <key>` header — what every OpenAI SDK sends. The header is honored only when the body fields are empty so a request can't smuggle two keys; the bearer value is mapped into AgentBYOK.APIKey and routed through the same overlay path.
The server-level BearerAuth middleware also consumes the Authorization header (validating user tokens) but only when --no-auth is off. In no-auth mode the header passes through to this handler untouched; in auth mode the user token IS the bearer, so BYOK via header is not available — fall back to body fields.
func (*Handlers) HandleCreateDBRecord ¶
HandleCreateDBRecord inserts a new record into a table. POST /api/db/tables/:table/records
func (*Handlers) HandleCreateProject ¶
HandleCreateProject handles POST /api/projects
func (*Handlers) HandleDeleteDBRecord ¶
HandleDeleteDBRecord deletes a record by primary key. DELETE /api/db/tables/:table/records/:id
func (*Handlers) HandleDeleteOASTInteraction ¶
HandleDeleteOASTInteraction handles DELETE /api/oast-interactions/:id
func (*Handlers) HandleDeleteProject ¶
HandleDeleteProject handles DELETE /api/projects/:uuid
func (*Handlers) HandleDeleteRecord ¶
HandleDeleteRecord handles DELETE /api/http-records/:uuid — deletes a single HTTP record by UUID.
func (*Handlers) HandleDeleteScan ¶
HandleDeleteScan handles DELETE /api/scans/:uuid — deletes a scan record.
func (*Handlers) HandleDiagnostics ¶
HandleDiagnostics handles GET /api/diagnostics — returns a system readiness report.
func (*Handlers) HandleEditExtension ¶
HandleEditExtension handles PUT /api/extensions/:name
func (*Handlers) HandleGetConfig ¶
HandleGetConfig handles GET /api/config — returns flattened config entries. Query params:
- filter: substring match on key (optional)
- show_sensitive: "true" to show unredacted sensitive values (optional)
func (*Handlers) HandleGetDBRecord ¶
HandleGetDBRecord returns a single record by primary key. GET /api/db/tables/:table/records/:id
func (*Handlers) HandleGetExtension ¶
HandleGetExtension handles GET /api/extensions/:name Returns full extension metadata plus raw file content.
func (*Handlers) HandleGetOASTInteraction ¶
HandleGetOASTInteraction handles GET /api/oast-interactions/:id
func (*Handlers) HandleGetProject ¶
HandleGetProject handles GET /api/projects/:uuid
func (*Handlers) HandleGetProjectStats ¶
HandleGetProjectStats handles GET /api/projects/:uuid/stats — returns just the aggregated stats for a project, without the project metadata. Useful when the UI needs to refresh stats independently of the project record.
func (*Handlers) HandleGetRecord ¶
HandleGetRecord handles GET /api/http-records/:uuid — returns a single HTTP record with full blob fields.
func (*Handlers) HandleGetScan ¶
HandleGetScan handles GET /api/scans/:uuid — returns a single scan by UUID.
func (*Handlers) HandleGetScanLogs ¶
HandleGetScanLogs handles GET /api/scans/:uuid/logs — returns scan logs.
Response format is chosen by the content source in the same priority order as the `vigolium log <uuid>` CLI command:
If {sessions_dir}/{scanUUID}/runtime.log exists, serve its contents as text/plain. Matches what the operator sees when tailing the CLI log. ANSI colors are preserved by default; pass ?strip=1 to remove them.
Otherwise, fall back to the scan_logs database table and return the structured JSON envelope ({"logs": [...], "total": N}) that older clients depend on. This fallback is the legacy path used by scans that predate runtime.log persistence.
func (*Handlers) HandleGetScope ¶
HandleGetScope handles GET /api/scope — returns the current scope config.
func (*Handlers) HandleHealth ¶
HandleHealth handles GET /health — a liveness probe. It reports that the process/event loop is alive and intentionally does NOT touch the database, so it never fails just because the DB is momentarily slow.
func (*Handlers) HandleImport ¶
HandleImport handles POST /api/import — imports scan data into the database from one of three input shapes, dispatched on Content-Type:
- multipart/form-data with file=*.jsonl|*.ndjson: bulk JSONL import.
- multipart/form-data with file=*.tar.gz|*.tgz|*.zip: archive containing audit output or JSONL files.
- application/json with {"url": "gs://..."}: backend fetches the archive or JSONL from cloud storage, then imports it.
All shapes accept an optional `agentic_scan_uuid` to attach imported findings to an existing scan instead of creating a new one. For multipart requests it's a form field; for JSON it's a body field.
func (*Handlers) HandleIngestHTTP ¶
HandleIngestHTTP handles POST /api/ingest-http
func (*Handlers) HandleListDBRecords ¶
HandleListDBRecords returns paginated, filtered records from any table. GET /api/db/tables/:table/records
func (*Handlers) HandleListDBTableColumns ¶
HandleListDBTableColumns returns column metadata for a specific table. GET /api/db/tables/:table/columns
func (*Handlers) HandleListDBTables ¶
HandleListDBTables returns all database tables with row counts. GET /api/db/tables
func (*Handlers) HandleListExtensionAPI ¶
HandleListExtensionAPI handles GET /api/extensions/docs Optional query params: ?search=<text>
func (*Handlers) HandleListExtensions ¶
HandleListExtensions handles GET /api/extensions Optional query params: ?type=active|passive|pre_hook|post_hook, ?search=<text>
func (*Handlers) HandleListModules ¶
HandleListModules handles GET /api/modules?search=xss&tag=spring
func (*Handlers) HandleListOASTInteractions ¶
HandleListOASTInteractions handles GET /api/oast-interactions
func (*Handlers) HandleListProjects ¶
HandleListProjects handles GET /api/projects
func (*Handlers) HandleListRecords ¶
HandleListRecords handles GET /api/http-records
func (*Handlers) HandleListScans ¶
HandleListScans handles GET /api/scans — returns paginated scan history.
func (*Handlers) HandleLogin ¶
HandleLogin handles POST /api/auth/login. Validates username + access_code and returns user info with a Bearer token.
func (*Handlers) HandleMetrics ¶
HandleMetrics handles GET /metrics — serves Prometheus metrics.
func (*Handlers) HandlePauseScan ¶
HandlePauseScan handles POST /api/scans/:uuid/pause — pauses a running scan.
func (*Handlers) HandleReady ¶
HandleReady handles GET /ready — a readiness probe distinct from liveness. It reports 200 only when the server can actually serve work: the database responds to a lightweight ping within a short timeout and the record writer is still accepting writes. Otherwise it returns 503 so an orchestrator routes traffic elsewhere without killing the (live) process.
func (*Handlers) HandleResumeScan ¶
HandleResumeScan handles POST /api/scans/:uuid/resume — resumes a paused scan.
func (*Handlers) HandleRunScan ¶
HandleRunScan handles POST /api/scans/run — triggers an async target-based scan. This route only accepts target URLs. Use POST /api/scan-all-records to scan DB records.
func (*Handlers) HandleScanAllRecords ¶
HandleScanAllRecords handles POST /api/scan-all-records — scans existing HTTP records from the database with optional filtering by hostname, method, path, status code, etc.
func (*Handlers) HandleScanRecords ¶
HandleScanRecords handles POST /api/scan-records — starts a scan on specific HTTP records by UUID.
func (*Handlers) HandleScanRequest ¶
HandleScanRequest handles POST /api/scan-request — scans a raw HTTP request asynchronously.
func (*Handlers) HandleScanStatus ¶
HandleScanStatus handles GET /api/scan/status — returns current scan state. Accepts optional ?project= query param to check a specific project.
func (*Handlers) HandleScanURL ¶
HandleScanURL handles POST /api/scan-url — scans a single URL asynchronously.
func (*Handlers) HandleServerInfo ¶
HandleServerInfo handles GET /server-info.
func (*Handlers) HandleStats ¶
HandleStats handles GET /api/stats — returns aggregated scan statistics.
func (*Handlers) HandleStopScan ¶
HandleStopScan handles POST /api/scans/:uuid/stop — stops a specific running scan.
func (*Handlers) HandleStorageDownloadResults ¶
HandleStorageDownloadResults handles GET /api/storage/results/:scan_uuid. Downloads the result bundle for a native scan or agentic scan.
func (*Handlers) HandleStorageDownloadSource ¶
HandleStorageDownloadSource handles GET /api/storage/source/:key. Downloads a source file from <bucket>/<project-uuid>/ugc/:key.
func (*Handlers) HandleStoragePresign ¶
HandleStoragePresign handles POST /api/storage/presign. Generates presigned URLs for direct upload/download.
func (*Handlers) HandleStorageUploadSource ¶
HandleStorageUploadSource handles POST /api/storage/upload-source. Accepts multipart file upload and stores it in <bucket>/<project-uuid>/ugc/<filename>.
func (*Handlers) HandleSwaggerSpec ¶
HandleSwaggerSpec serves the OpenAPI specification JSON.
func (*Handlers) HandleUpdateAgenticScan ¶
HandleUpdateAgenticScan handles POST /api/agent/scans/:uuid/update — partially updates an existing agentic scan record. Fields omitted from the body are left unchanged. Immutable fields (id, uuid, project_uuid, created_at) are ignored if present in the request body.
func (*Handlers) HandleUpdateConfig ¶
HandleUpdateConfig handles POST /api/config — updates multiple config values. Accepts JSON body: {"dot.key1": "value1", "dot.key2": "value2"}
func (*Handlers) HandleUpdateDBRecord ¶
HandleUpdateDBRecord updates fields on an existing record. PUT /api/db/tables/:table/records/:id
func (*Handlers) HandleUpdateProject ¶
HandleUpdateProject handles PUT /api/projects/:uuid
func (*Handlers) HandleUpdateScan ¶
HandleUpdateScan handles POST /api/scans/:uuid/update — partially updates an existing native scan record. Fields omitted from the body are left unchanged. Immutable fields (uuid, project_uuid, created_at) are ignored if present in the request body — the UUID is taken from the path, and project ownership is validated against X-Project-UUID before the write.
func (*Handlers) HandleUpdateScope ¶
HandleUpdateScope handles POST /api/scope — updates the scope config.
func (*Handlers) HandleUserInfo ¶
HandleUserInfo handles GET /api/user/info. Returns the authenticated user's identity and role.
func (*Handlers) IsScanRunning ¶
IsScanRunning reports whether any scan is currently running (across all projects). Implements metrics.ScanStateProvider.
type HealthResponse ¶
HealthResponse is the response for GET /health.
type ImportRequest ¶
type ImportRequest struct {
URL string `json:"url"`
AgenticScanUUID string `json:"agentic_scan_uuid,omitempty"`
}
ImportRequest is the JSON body for POST /api/import when pointing the server at a cloud-stored archive instead of uploading bytes. URL must be gs:// (or gcs:// alias). AgenticScanUUID, when set, attaches findings to an existing scan row in the same project instead of creating a new one.
type ImportResponse ¶
type ImportResponse struct {
AgenticScanUUID string `json:"agentic_scan_uuid,omitempty"`
CreatedNew bool `json:"created_new"`
RecordsImported int `json:"records_imported"`
FindingsTotal int `json:"findings_total"`
FindingsSaved int `json:"findings_saved"`
FindingsSkipped int `json:"findings_skipped"`
ParseErrors int `json:"parse_errors,omitempty"`
Severity map[string]int `json:"severity,omitempty"`
SessionDir string `json:"session_dir,omitempty"`
StorageURL string `json:"storage_url,omitempty"`
}
ImportResponse is the success response for POST /api/import.
type IngestHTTPRequest ¶
type IngestHTTPRequest struct {
InputMode string `json:"input_mode"`
URL string `json:"url,omitempty"`
Content string `json:"content,omitempty"`
ContentBase64 string `json:"content_base64,omitempty"`
HTTPRequestBase64 string `json:"http_request_base64,omitempty"`
HTTPResponseBase64 string `json:"http_response_base64,omitempty"`
}
IngestHTTPRequest is the request body for POST /api/ingest-http.
type IngestHTTPResponse ¶
type IngestHTTPResponse struct {
ProjectUUID string `json:"project_uuid,omitempty"`
Imported int `json:"imported"`
Skipped int `json:"skipped,omitempty"`
Errors []string `json:"errors,omitempty"`
Message string `json:"message"`
}
IngestHTTPResponse is the response for POST /api/ingest-http.
type LoginRequest ¶
type LoginRequest struct {
Username string `json:"username"`
AccessCode string `json:"access_code"`
}
LoginRequest is the request body for POST /api/auth/login.
type LoginResponse ¶
LoginResponse is the response for POST /api/auth/login.
type LoginUser ¶
type LoginUser struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Email string `json:"email"`
Role string `json:"role"`
}
LoginUser is the user info returned in a login response.
type ModuleCount ¶
ModuleCount holds total and enabled counts for a module type.
type ModuleInfo ¶
type ModuleInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
ShortDescription string `json:"short_description"`
ConfirmationCriteria string `json:"confirmation_criteria"`
Severity string `json:"severity"`
Confidence string `json:"confidence"`
ScanScope []string `json:"scan_scope"`
Tags []string `json:"tags"`
Type string `json:"type"` // "active" or "passive"
}
ModuleInfo is the response type for module listing.
type ModuleStats ¶
type ModuleStats struct {
Active ModuleCount `json:"active"`
Passive ModuleCount `json:"passive"`
}
ModuleStats holds module counts.
type PaginatedResponse ¶
type PaginatedResponse struct {
ProjectUUID string `json:"project_uuid,omitempty"`
Data interface{} `json:"data"`
Total int64 `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
HasMore bool `json:"has_more"`
}
PaginatedResponse wraps paginated results.
type ProjectFindingStats ¶
type ProjectFindingStats struct {
Total int64 `json:"total"`
Critical int64 `json:"critical"`
High int64 `json:"high"`
Medium int64 `json:"medium"`
Low int64 `json:"low"`
Info int64 `json:"info"`
}
ProjectFindingStats holds finding counts with severity breakdown.
type ProjectHTTPRecordStats ¶
type ProjectHTTPRecordStats struct {
Total int64 `json:"total"`
Success int64 `json:"success"` // 2xx
Redirect int64 `json:"redirect"` // 3xx
ClientErr int64 `json:"client_err"` // 4xx
ServerErr int64 `json:"server_err"` // 5xx
}
ProjectHTTPRecordStats holds HTTP record counts with status breakdown.
type ProjectRequest ¶
type ProjectRequest struct {
UUID string `json:"uuid,omitempty"`
Name string `json:"name"`
Description string `json:"description"`
OwnerUUID string `json:"owner_uuid"`
}
ProjectRequest is the request body for POST/PUT /api/projects.
UUID is optional on POST. When the cloud console eagerly provisions a scanner row for a Convex-managed project, it sends the Convex-side UUID so both systems agree on the same key. When omitted, the scanner mints a fresh UUID — preserving the standalone-CLI behavior.
type ProjectStats ¶
type ProjectStats struct {
HTTPRecords ProjectHTTPRecordStats `json:"http_records"`
Findings ProjectFindingStats `json:"findings"`
Scans int64 `json:"scans"`
AgenticScans int64 `json:"agentic_scans"`
OASTInteractions int64 `json:"oast_interactions"`
}
ProjectStats holds aggregated statistics for a project.
type ProjectWithStats ¶
type ProjectWithStats struct {
*database.Project
Stats ProjectStats `json:"stats"`
}
ProjectWithStats wraps a Project with its aggregated stats.
type ResolvedUser ¶
ResolvedUser is the identity attached to a request after auth resolution.
type RunScanRequest ¶
type RunScanRequest struct {
// Target URLs to scan (like -t). At least one target or url is required.
Targets []string `json:"targets,omitempty"`
// URLs is an alias for Targets.
URLs []string `json:"urls,omitempty"`
// DryRun validates params and creates scan record but does not launch the runner
DryRun bool `json:"dry_run"`
// Strategy preset: lite, balanced, deep
Strategy string `json:"strategy,omitempty"`
// Single phase isolation (like --only)
Only string `json:"only,omitempty"`
// Skip specific phases (like --skip)
Skip []string `json:"skip,omitempty"`
// Module IDs with fuzzy match (like -m)
Modules []string `json:"modules,omitempty"`
// Filter modules by tag (like --module-tag)
ModuleTags []string `json:"module_tags,omitempty"`
// Performance tuning
Concurrency int `json:"concurrency,omitempty"`
Timeout string `json:"timeout,omitempty"` // Go duration e.g. "30s"
MaxPerHost int `json:"max_per_host,omitempty"`
RateLimit int `json:"rate_limit,omitempty"`
// Max scan duration (like --scanning-max-duration)
ScanningMaxDuration string `json:"scanning_max_duration,omitempty"`
// Scope origin mode: all, relaxed, balanced, strict
ScopeOrigin string `json:"scope_origin,omitempty"`
// Heuristics check level: none, basic, advanced
HeuristicsCheck string `json:"heuristics_check,omitempty"`
// Custom HTTP headers
Headers map[string]string `json:"headers,omitempty"`
// Scanning profile name or path
ScanningProfile string `json:"scanning_profile,omitempty"`
// Intensity preset: quick, balanced, deep (resolves to scanning_profile + strategy)
Intensity string `json:"intensity,omitempty"`
// Upload results to cloud storage after scan completion
UploadResults bool `json:"upload_results,omitempty"`
// OutputFormats selects extra result formats to materialize on disk during
// the scan. Currently supports "jsonl" and "html". When set, files are
// written to <sessions_dir>/<scan_uuid>/output.<ext> and — if
// upload_results is also true — bundled into the uploaded tar.gz alongside
// runtime.log.
OutputFormats []string `json:"output_formats,omitempty"`
// Pin scan UUID (for cross-node sync). When set, the scan record is
// fetched-or-created with this UUID; if a record already exists, its
// project_uuid must match.
ScanUUID string `json:"scan_uuid,omitempty"`
}
RunScanRequest is the request body for POST /api/scans/run. This route only accepts target URLs — use /api/scan-all-records to scan DB records.
type ScanAllRecordsRequest ¶
type ScanAllRecordsRequest struct {
// Record selection filters (all optional — omit all to scan everything)
Hostname string `json:"hostname,omitempty"` // hostname filter (supports * wildcards)
Methods []string `json:"methods,omitempty"` // HTTP methods filter
Path string `json:"path,omitempty"` // path filter (supports * wildcards)
StatusCodes []int `json:"status_codes,omitempty"` // status code filter
Source string `json:"source,omitempty"` // record source filter
Search string `json:"search,omitempty"` // search across URL/path
MinRiskScore int `json:"min_risk_score,omitempty"` // minimum risk score
// MinSurfaceScore filters on the deterministic attack-surface score (0-100)
// written by the surface_scoring passive module, which owns the scale.
MinSurfaceScore int `json:"min_surface_score,omitempty"`
Remark string `json:"remark,omitempty"` // remark substring filter
// Force full rescan (ignore cursor, scan all matching records)
Force bool `json:"force"`
// DryRun validates params, counts matching records, but does not launch the runner
DryRun bool `json:"dry_run"`
// Module IDs with fuzzy match (like -m)
Modules []string `json:"modules,omitempty"`
// Filter modules by tag (like --module-tag)
ModuleTags []string `json:"module_tags,omitempty"`
// Performance tuning
Concurrency int `json:"concurrency,omitempty"`
Timeout string `json:"timeout,omitempty"` // Go duration e.g. "30s"
MaxPerHost int `json:"max_per_host,omitempty"`
RateLimit int `json:"rate_limit,omitempty"`
// Max scan duration (like --scanning-max-duration)
ScanningMaxDuration string `json:"scanning_max_duration,omitempty"`
// Heuristics check level: none, basic, advanced
HeuristicsCheck string `json:"heuristics_check,omitempty"`
// Custom HTTP headers
Headers map[string]string `json:"headers,omitempty"`
// Scanning profile name or path
ScanningProfile string `json:"scanning_profile,omitempty"`
// Intensity preset: quick, balanced, deep (resolves to scanning_profile + strategy)
Intensity string `json:"intensity,omitempty"`
}
ScanAllRecordsRequest is the request body for POST /api/scan-all-records. Scans existing HTTP records from the database with optional filtering.
type ScanRecordsRequest ¶
type ScanRecordsRequest struct {
RecordUUIDs []string `json:"record_uuids"`
EnableModules []string `json:"enable_modules,omitempty"`
}
ScanRecordsRequest is the request body for POST /api/scan-records.
type ScanRequestRequest ¶
type ScanRequestRequest struct {
// HTTPRequestBase64 is the preferred field name for the base64-encoded raw HTTP request.
// RawRequest is accepted as an alias for backward compatibility.
HTTPRequestBase64 string `json:"http_request_base64,omitempty"`
RawRequest string `json:"raw_request,omitempty"`
// HTTPResponseBase64 is the preferred field name for the base64-encoded raw HTTP response
// (optional, for Burp-style request+response pairs). RawResponse is accepted as an alias.
HTTPResponseBase64 string `json:"http_response_base64,omitempty"`
RawResponse string `json:"raw_response,omitempty"`
TargetURL string `json:"target_url"` // scheme://host override
Modules string `json:"modules"` // comma-separated module IDs
NoPassive bool `json:"no_passive"`
}
ScanRequestRequest is the request body for POST /api/scan-request.
func (*ScanRequestRequest) ReqBase64 ¶
func (r *ScanRequestRequest) ReqBase64() string
ReqBase64 returns the base64-encoded raw request, preferring http_request_base64 over raw_request.
func (*ScanRequestRequest) RespBase64 ¶
func (r *ScanRequestRequest) RespBase64() string
RespBase64 returns the base64-encoded raw response, preferring http_response_base64 over raw_response.
type ScanResponse ¶
type ScanResponse struct {
ProjectUUID string `json:"project_uuid,omitempty"`
ScanUUID string `json:"scan_uuid"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
RecordsToScan int64 `json:"records_to_scan,omitempty"`
TargetsCount int `json:"targets_count,omitempty"`
ScanMode string `json:"scan_mode,omitempty"` // "target", "full", "incremental"
}
ScanResponse is the response for POST /api/scans/run.
type ScanStatusResponse ¶
type ScanStatusResponse struct {
ProjectUUID string `json:"project_uuid,omitempty"`
ScanUUID string `json:"scan_uuid,omitempty"`
Running bool `json:"running"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
}
ScanStatusResponse is the response for GET /api/scan/status.
type ScanURLRequest ¶
type ScanURLRequest struct {
URL string `json:"url"`
Method string `json:"method"` // default GET
Body string `json:"body"`
Headers map[string]string `json:"headers"`
Modules string `json:"modules"` // comma-separated module IDs
NoPassive bool `json:"no_passive"`
}
ScanURLRequest is the request body for POST /api/scan-url.
type ScopeUpdateResponse ¶
type ScopeUpdateResponse struct {
Message string `json:"message"`
Scope interface{} `json:"scope"`
}
ScopeUpdateResponse is the response for POST /api/scope.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the HTTP API server.
func NewServer ¶
func NewServer(cfg ServerConfig, q queue.Queue, db *database.DB, repo *database.Repository, settings *config.Settings, httpRequester *vhttp.Requester, svc *services.Services) *Server
NewServer creates a new HTTP API server.
svc is the shared *services.Services the caller built for httpRequester. It carries the dedup manager, host rate limiter, and scan Options used by the core executor — passing it through lets API-triggered scans reuse the same rate-limiter instance the ingestion path uses, rather than running unbounded. Safe to pass nil (handlers will fall back to the previous minimal-wiring behavior).
func (*Server) Config ¶
func (s *Server) Config() ServerConfig
Config returns the server configuration.
func (*Server) OnConfigReload ¶
OnConfigReload registers fn to run after the config watcher hot-reloads one or more sections at runtime; fn receives the changed section names. No-op when the watcher failed to start. Register before Start(). Used by the CLI to print operator-facing reload feedback.
func (*Server) ProxyCACertPath ¶
ProxyCACertPath returns the on-disk path of the ingest-proxy MITM CA certificate, or "" when HTTPS interception is not enabled. Used by the CLI to surface the trust anchor at startup.
type ServerConfig ¶
type ServerConfig struct {
ServiceAddr string // e.g. "0.0.0.0:9002"
BurpBridgeURL string // optional loopback Burp listener merged into GET /api/http-records
IngestProxyAddr string // e.g. "0.0.0.0:9003" (empty = disabled)
IngestProxyMITM bool // Intercept HTTPS via a generated CA (records + scans TLS traffic)
IngestProxyInsecure bool // Skip upstream TLS verification when intercepting HTTPS
IngestProxyCADir string // Directory holding the MITM CA (empty = ~/.vigolium/ca)
APIKeys []string // Valid Bearer tokens
NoAuth bool // If true, skip auth
ScanOnReceive bool
DisableFetchResponse bool
Concurrency int // Worker concurrency for API-triggered scans
ReadTimeout time.Duration
// WriteTimeout bounds how long the whole response may take to write. It must
// be 0 (unlimited) for the SSE agent/audit streams this server hosts — a
// finite cap severs a stream that outlives it. Non-streaming write protection
// is provided by IdleTimeout and handler-level deadlines instead. 0 = default
// (unlimited).
WriteTimeout time.Duration
IdleTimeout time.Duration
ShutdownTimeout time.Duration
// MaxUploadBytes is the framework-level request body ceiling (Fiber BodyLimit).
// It must exceed the ordinary DefaultBodyLimitMiddleware cap so the large-upload
// routes (/api/import, /api/storage/upload-source) aren't rejected by the
// framework before the route exemption runs. 0 = default (512 MiB).
MaxUploadBytes int
CORSAllowedOrigins string
UserStore *UserStore // File-based user store (nil = legacy auth only)
ScanQueueCapacity int // 0 = reject with 409 when busy (default), >0 = per-project queue depth
NoAgent bool // If true, disable all agent endpoints and warm sessions
ViewOnly bool // If true, only serve GET/viewer routes (no scanning, ingestion, or agent)
DemoOnly bool // If true, expose only the demo allowlist (subset of GET endpoints)
License string // Optional license tag surfaced in /server-info (configured in server.license)
EnableMetrics bool // Enable Prometheus /metrics endpoint
NoSwagger bool // If true, disable Swagger UI and spec endpoint
Debug bool // Log raw request body, query params, and headers
AgentHeavyMax int // Max concurrent heavy agent runs (autopilot/swarm); 0 = default 5
AgentLightMax int // Max concurrent light agent runs (query/chat); 0 = default 10
AgentQueueTimeout time.Duration // Max wait time when all agent slots busy; 0 = default 30s
// AgentHeavyPerProject caps how many concurrent heavy agent runs a
// single project can hold at once. 0 = default 2; negative = disable
// the per-project cap (only the global AgentHeavyMax applies). Used
// to prevent one tenant from draining the cluster's heavy slot pool.
AgentHeavyPerProject int
Version string // Injected version string for /server-info
Author string
Commit string
BuildTime string
// MirrorFSPath, when set, mirrors every ingested HTTP record and finding to
// a flat filesystem tree under this directory (in addition to the database),
// so an external agent can read live traffic as files. See --mirror-fs.
MirrorFSPath string
// ConfigPath is the effective config file the server loaded settings from
// (honors the --config flag). The config watcher watches this file for
// hot-reload. Empty falls back to config.ConfigFilePath() (the default
// ~/.vigolium/vigolium-configs.yaml).
ConfigPath string
}
ServerConfig holds configuration for the API server.
func DefaultServerConfig ¶
func DefaultServerConfig() ServerConfig
type ServerInfoResponse ¶
type ServerInfoResponse struct {
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author"`
Docs string `json:"docs"`
BuildTime string `json:"build_time,omitempty"`
Commit string `json:"commit,omitempty"`
Uptime string `json:"uptime"`
ServiceAddr string `json:"service_addr"`
ProxyAddr string `json:"proxy_addr,omitempty"`
QueueDepth int64 `json:"queue_depth"`
TotalRecords int64 `json:"total_records"`
TotalFindings int64 `json:"total_findings"`
License string `json:"license,omitempty"`
LicenseSPDX string `json:"license_spdx"`
Source string `json:"source"`
DemoOnly bool `json:"demo_only,omitempty"`
ViewOnly bool `json:"view_only,omitempty"`
}
ServerInfoResponse is the response for GET /server-info.
type StatsResponse ¶
type StatsResponse struct {
ProjectUUID string `json:"project_uuid,omitempty"`
HTTPRecords HTTPRecordStats `json:"http_records"`
Modules ModuleStats `json:"modules"`
Findings FindingStats `json:"findings"`
}
StatsResponse is the response for GET /api/stats.
type StoragePresignRequest ¶
type StoragePresignRequest struct {
Key string `json:"key"`
Method string `json:"method,omitempty"` // GET (default) or PUT
ExpirySeconds int `json:"expiry_seconds,omitempty"`
}
StoragePresignRequest is the request body for POST /api/storage/presign.
type StoragePresignResponse ¶
type StoragePresignResponse struct {
URL string `json:"url"`
Key string `json:"key"`
Method string `json:"method"`
Expiry int `json:"expiry_seconds"`
}
StoragePresignResponse is the response for POST /api/storage/presign.
type StorageUploadResponse ¶
type StorageUploadResponse struct {
StorageURL string `json:"storage_url"`
Key string `json:"key"`
Filename string `json:"filename"`
Size int64 `json:"size"`
Message string `json:"message"`
}
StorageUploadResponse is the response for POST /api/storage/upload-source.
type UpdateFindingStatusRequest ¶
type UpdateFindingStatusRequest struct {
Status string `json:"status"`
}
UpdateFindingStatusRequest is the JSON body for PATCH /api/findings/:id/status.
type UserStore ¶
type UserStore struct {
// contains filtered or unexported fields
}
UserStore maps access codes to resolved users for O(1) lookup.
func NewUserStore ¶
NewUserStore builds a store from a slice of FileUser entries. Each user gets a deterministic UUID v5 derived from their email (or name if no email).
func (*UserStore) Lookup ¶
func (s *UserStore) Lookup(accessCode string) *ResolvedUser
Lookup returns the resolved user for an access code, or nil if not found.
func (*UserStore) LookupByNameAndCode ¶
func (s *UserStore) LookupByNameAndCode(name, accessCode string) *ResolvedUser
LookupByNameAndCode returns the resolved user matching both name and access code, or nil.
Source Files
¶
- agentic_scans.go
- doc.go
- errors.go
- handlers.go
- handlers_agent.go
- handlers_agent_audit.go
- handlers_agent_audit_combined.go
- handlers_agent_audit_cred.go
- handlers_agent_audit_runner.go
- handlers_agent_autopilot.go
- handlers_agent_byok_olium.go
- handlers_agent_swarm.go
- handlers_auth.go
- handlers_burp_bridge.go
- handlers_config.go
- handlers_db.go
- handlers_diagnostics.go
- handlers_extensions.go
- handlers_findings.go
- handlers_import.go
- handlers_ingest.go
- handlers_modules.go
- handlers_oast.go
- handlers_project.go
- handlers_records.go
- handlers_scan.go
- handlers_scan_records.go
- handlers_scan_update.go
- handlers_scan_url.go
- handlers_scope.go
- handlers_stats.go
- handlers_storage.go
- logtail.go
- middleware.go
- proxy.go
- redact.go
- routes.go
- scan_runtime_log.go
- server.go
- swagger.go
- types.go
- userstore.go