Environment variables
Copy .env.example to .env for local development.
Docker Compose deployments use additional variables documented in README.md.
Core services
| Variable | Required | Description |
DATABASE_URL | Yes | PostgreSQL connection string |
REDIS_URL | Yes | Redis for BullMQ job queue |
MINIO_ENDPOINT | Yes | S3-compatible storage host |
MINIO_PORT | Yes | MinIO port (e.g. 9000) |
MINIO_ACCESS_KEY | Yes | MinIO access key |
MINIO_SECRET_KEY | Yes | MinIO secret key |
MINIO_USE_SSL | No | true / false |
MINIO_BUCKET | Yes | Bucket for scan artifacts |
Authentication
| Variable | Description |
NEXTAUTH_SECRET | Session signing / encryption secret (long random string) |
NEXTAUTH_URL | Public app URL (e.g. http://localhost:3000) |
ADMIN_EMAIL | Seed script default admin email |
ADMIN_PASSWORD | Seed script default admin password — change after first login |
NEXT_PUBLIC_SOURCE_CODE_URL | Optional link on login page |
GitHub
| Variable | Description |
GITHUB_ID / GITHUB_SECRET | Optional NextAuth GitHub login |
GITHUB_OAUTH_CLIENT_ID | OAuth app for Repositories + fix PR (falls back to GITHUB_ID) |
GITHUB_OAUTH_CLIENT_SECRET | OAuth secret (falls back to GITHUB_SECRET) |
TOKEN_ENCRYPTION_KEY | Encrypts stored GitHub tokens (defaults to NEXTAUTH_SECRET) |
GITHUB_WEBHOOK_SECRET | HMAC secret for /api/webhooks/github |
GITHUB_WEBHOOK_MAIN_SCAN_TYPE | Default-branch push scan: SAST_ONLY or FULL |
GITHUB_PR_TOKEN / GITHUB_TOKEN | Legacy PAT — not used when OAuth is connected |
Authorization callback URL:
{NEXTAUTH_URL}/api/integrations/github/callback
OAuth scopes requested: read:user repo
Bitbucket Cloud
App password and workspace are configured in Settings → Integrations (encrypted in DB). Webhook secret optional in UI or env.
| Variable | Description |
BITBUCKET_WEBHOOK_SECRET | HMAC secret for /api/webhooks/bitbucket (X-Hub-Signature) |
Webhook triggers: repository push, pull request created, pull request updated → PR events queue INCREMENTAL scans.
Azure DevOps
Organization name and PAT are configured in Settings → Integrations. Service hooks use Basic auth (password only).
| Variable | Description |
AZURE_DEVOPS_WEBHOOK_SECRET | Basic auth password for /api/webhooks/azure-devops |
Service hook events: git.push, git.pullrequest.created, git.pullrequest.updated.
Default-branch webhook scans
| Variable | Default | Description |
GITHUB_WEBHOOK_MAIN_SCAN_TYPE | SAST_ONLY | Scan type after push/merge to default branch (GitHub, Bitbucket, Azure) |
GitLab
| Variable | Description |
GITLAB_ID / GITLAB_SECRET | Optional GitLab OAuth |
GITLAB_URL | GitLab instance base (default https://gitlab.com) |
LLM & worker
| Variable | Default | Description |
OPENROUTER_API_KEY | — | Cloud LLM via OpenRouter |
OPENROUTER_MODEL | — | Default model when using OpenRouter env key |
WORKER_CONCURRENCY | 2 | Parallel scan jobs per worker |
MAX_LLM_CONCURRENCY | 5 | Parallel LLM calls within a scan |
LLM_CHUNK_TOKENS | 3000 | Code chunk size for API models |
LLM_CHUNK_OVERLAP_TOKENS | 200 | Overlap between chunks |
LLM_MAX_RESPONSE_TOKENS | 4096 | Max LLM response tokens |
OLLAMA_CHUNK_TOKENS | 1200 | Chunk size for local Ollama |
OLLAMA_CHUNK_OVERLAP_TOKENS | 100 | Ollama overlap |
OLLAMA_MAX_RESPONSE_TOKENS | 2048 | Ollama max response |
LLM_MIN_CONFIDENCE | 0.7 | Drop LLM findings below this confidence |
LLM_MASK_SECRETS | true | Replace secrets in code with placeholders before any request is sent to the LLM. Fix PRs still contain the original values. |
LLM_EXCLUDE_PATHS | (none) | Comma-separated globs of files never sent to the LLM (e.g. config/prod/**,*.tfvars). Private key and keystore files are always excluded; rule-based scanners still scan them. |
OLLAMA_HOST | — | Docker: host Ollama URL (see README) |
Compiled-code scanning
Compiled artifacts in a scan — JAR / WAR / EAR / .class (Vineflower), Android APK / AAB / DEX (jadx) and .NET DLL / EXE (ILSpy) — are decompiled in the worker and the decompiled source is reviewed by AI SAST, rule-based SAST (OpenGrep) and the secrets scanners. A single .jar, .war, .ear, .apk, .aab, .dll or .exe can also be uploaded as the scan source. Findings show as app.apk!/com/example/Login.java:42; their line numbers refer to the decompiled source. Native (non-.NET) DLL/EXE cannot be decompiled and are listed as skipped. Artifacts in dependency folders (WEB-INF/lib, lib/, libs/, node_modules, packages/, .m2, .gradle, vendor), well-known library assemblies and library packages inside an artifact (android/, androidx/, kotlin/, com/google/, org/apache/ …) are skipped: dependency vulnerabilities are SCA's job. Build output (target/, build/, bin/ …) is skipped when the scan already contains that language's source.
| Variable | Default | Description |
ENABLE_COMPILED_SCAN | true | Decompile and scan compiled artifacts. false turns it off. |
COMPILED_SCAN_MAX_ARTIFACT_MB | 200 | Larger artifacts are skipped (archives may also unpack to at most 10× this). |
COMPILED_SCAN_MAX_ARTIFACTS | 25 | Artifacts decompiled per scan, including nested ones (a WAR inside an EAR). |
COMPILED_SCAN_MAX_FILES | 5000 | Decompiled files added to a scan. Source files are kept before resources. Also bounds AI SAST cost on large apps. |
COMPILED_SCAN_MAX_OUTPUT_MB | 200 | Decompiled bytes added to a scan. |
COMPILED_SCAN_TIMEOUT_SECONDS | 600 | Per artifact; the decompiler is killed after this (partial output is kept). |
COMPILED_SCAN_TOTAL_TIMEOUT_SECONDS | 1800 | The whole decompile step of a scan. |
COMPILED_SCAN_SKIP_THIRD_PARTY | true | false also decompiles dependency folders, library assemblies and library packages. |
COMPILED_SCAN_EXCLUDE_PACKAGES | (none) | More packages / namespaces to skip, comma-separated (com.acme.generated,Acme.Vendor). |
COMPILED_SCAN_INCLUDE_PACKAGES | (none) | Packages never skipped, even under a library prefix (org.apache.myproject). |
COMPILED_SCAN_THREADS | 2 | Decompiler threads per artifact. |
COMPILED_SCAN_JAVA_OPTS | -XX:MaxRAMPercentage=50 | JVM options for jadx and Vineflower. |
JADX_BIN, VINEFLOWER_BIN, ILSPYCMD_BIN | on PATH | Decompiler overrides (the worker image ships all three). |
Data retention
Nothing is deleted by default. Retention runs in the worker at most once every 6 hours and records what it deleted in each organization's audit log.
| Variable | Default | Description |
AUDIT_LOG_RETENTION_DAYS | forever | Audit entries older than this (minimum 30) are archived to object storage and deleted. Organizations can override it in Settings → Audit log. |
UPLOAD_RETENTION_DAYS | forever | Uploaded source archives are deleted this many days after upload (minimum 1). Scan results stay; rescanning that project asks for the archive again. Archives used by a queued, running or paused scan are kept. |
SCAN_HISTORY_RETENTION_DAYS | forever | Earlier scans of each repository (with their findings), trend snapshots and finished AI fix runs older than this (minimum 30) are deleted. Each repository's latest scan, latest completed scan, and latest snapshot per scan type are always kept. |
Supply chain & SCA
See Supply chain security for what these control.
Every external lookup degrades gracefully: if a source is unreachable the scan
continues and reports less, rather than reporting a clean result it cannot support.
License policy
| Variable | Default | Description |
LICENSE_POLICY_DENY | AGPL-*,GPL-*,SSPL-*,BUSL-*,CC-BY-NC-*,Commons-Clause,Elastic-2.0 | Licenses that fail policy (HIGH finding). SPDX IDs or PREFIX-* wildcards, comma-separated |
LICENSE_POLICY_WARN | LGPL-*,MPL-*,EPL-*,CDDL-*,OSL-*,MS-RL,CPAL-* | Licenses allowed but flagged for review (LOW finding) |
LICENSE_POLICY_FLAG_UNKNOWN | false | Report dependencies whose license could not be determined |
Dependency metadata (deps.dev)
| Variable | Default | Description |
ENABLE_DEPS_DEV | true | Set false to disable license, provenance, and dependency-path lookups entirely (air-gapped) |
DEPS_DEV_API_URL | https://api.deps.dev | Override to point at a mirror |
DEPS_DEV_TIMEOUT_MS | 10000 | Per-request timeout |
DEPS_DEV_CONCURRENCY | 10 | Parallel metadata requests |
DEPS_DEV_CACHE_TTL_MS | 21600000 | Metadata cache lifetime (6h). Package metadata is immutable per version, so repeat scans are nearly free |
DEPS_DEV_MAX_CACHE_ENTRIES | 20000 | Cache size bound |
DEPS_DEV_MAX_GRAPH_FETCHES | 60 | Max dependency graphs fetched per scan when explaining transitive vulnerabilities. Truncation is reported in the scan log |
Exploitation signals
| Variable | Default | Description |
ENABLE_EPSS_KEV | true | Set false to disable EPSS and CISA KEV enrichment |
EPSS_API_TIMEOUT | 10000 | EPSS request timeout |
AI triage of dependency CVEs
Triage reads the published advisory text so exploitability conditions come from the
advisory rather than the model's recollection. These budgets keep the advisory
inside the model's context window — local models default to a much smaller window,
so they use smaller values.
| Variable | Default | Description |
SCA_TRIAGE_ADVISORY_CHARS | 1500 | Advisory characters per CVE (API models) |
SCA_TRIAGE_ADVISORY_CHARS_OLLAMA | 500 | Advisory characters per CVE (local models) |
SCA_TRIAGE_BATCH_SIZE | 20 | CVEs per triage request (API models) |
SCA_TRIAGE_BATCH_SIZE_OLLAMA | 8 | CVEs per triage request (local models) |
MALICIOUS_PKG_MIN_CONFIDENCE | 0.8 | Minimum confidence for AI malicious-package findings |
Raising the advisory or batch values on a local model can silently overflow its
context window and degrade triage quality. Increase the model's context size first.
Container image scanning
| Variable | Default | Description |
TRIVY_CACHE_DIR | /var/cache/trivy | Trivy database location. Mount a pre-populated cache here for air-gapped scanning |
Trivy ships inside the worker image, so no host installation is required. When the
vulnerability database mode is offline, Trivy scans against the
mounted cache without attempting an update.
Email (SMTP)
| Variable | Description |
SMTP_HOST | Mail server hostname |
SMTP_PORT | Usually 587 (TLS) or 465 |
SMTP_USER / SMTP_PASSWORD | Credentials |
SMTP_FROM | From address |
SMTP_TLS | true to use STARTTLS |
Local dev: use Mailpit or similar on port 1025/8025.
Docker-only (README)
Production Compose may also define:
POSTGRES_PASSWORD, PEPPER_PORT, WORKER_REPLICAS
PEPPER_IMAGE, PEPPER_VERSION for private registries
UI settings (LLM provider, policies, build gates) are stored in PostgreSQL per organization.
Environment variables act as defaults and fallbacks for LLM keys and SMTP.