Configuration Reference
All configuration is via environment variables — no config files read at runtime. Set them in your docker-compose.yml or .env file.
Proxy (ghost-proxy)
| Variable | Default | Description |
|---|---|---|
GOSTLY_LICENSE_KEYrequired | — | License key issued from the Gostly dashboard. Gates tier-specific features. |
BACKEND_URLrequired | — | Base URL of the service to proxy in LEARN mode (e.g. http://your-service:3000 or https://api.example.com). Any reachable HTTP endpoint — production access not required. |
MOCK_DIR | /data/mocks | Path to the mock library directory inside the container. Must match the volume mount. |
MODE_FILE_PATH | /data/mode.txt | Path to the mode file. The proxy reads this on startup and watches it for changes. |
TRAFFIC_LOG_DIR | /data/traffic | Directory where raw JSONL traffic files are written during LEARN mode (Pro/Team). |
API_URL | http://ghost-web:8000 | Internal URL of the ghost-web control plane. Used for mode changes and reload signals. |
INFERENCE_URL | http://ghost-inference:5000 | Internal URL of the inference server. Required for AI generation (Pro+). |
AI_CONFIDENCE_THRESHOLD | 0.70 | Minimum confidence score for an AI-generated response to be served. Below this the proxy returns 503 (Pro+). |
PROXY_PORT | 8080 | Port the proxy listens on. |
ACCEPT_INVALID_CERTS | false | Skip TLS verification for the upstream. Emits a startup warning. Only for staging environments with self-signed certs. |
REDACT_HEADERS | — | Comma-separated list of additional headers to redact. Adds to the non-overridable floor — cannot replace it. |
RUST_LOG | info | Log level for the proxy. One of: error, warn, info, debug, trace. |
Control plane (ghost-web)
ghost-web serves both the operator dashboard on port 3000 and the control plane API on port 8000 from the same container.
| Variable | Default | Description |
|---|---|---|
GOSTLY_LICENSE_KEYrequired | — | Must match the license key used by the proxy. |
DATABASE_URLrequired | — | PostgreSQL connection string (e.g. postgresql://ghost:ghost@ghost-postgres:5432/ghost). |
GOSTLY_PLATFORM_URL | https://gostly.ai | URL of the Gostly license platform. Only change this for air-gapped deployments. |
AGENT_URL | http://ghost-proxy:8080 | Internal URL of the proxy. Used to send reload signals. |
INFERENCE_URL | http://ghost-inference:5000 | Internal URL of the inference server (Pro+). |
API_BASE_URL | http://ghost-web:8000 | Self-referential URL used by the inference server to fetch training data. |
MOCK_DIR | /data/mocks | Shared mock library directory. Must match the proxy's MOCK_DIR. |
TRAFFIC_LOG_DIR | /data/traffic | Shared traffic JSONL directory. Must match the proxy's TRAFFIC_LOG_DIR. |
LICENSE_CACHE_TTL | 300 | Seconds to cache license validation results. |
LICENSE_STALE_TTL | 14400 | Seconds to serve stale cache if the license server is unreachable. |
LOG_LEVEL | info | Structured log level. One of: debug, info, warning, error. |
Inference server (ghost-inference, Pro+)
The inference server is optional and only included in Pro/Team stacks. Both flags default to false — enable them explicitly.
| Variable | Default | Description |
|---|---|---|
ENABLE_GENERATION | false | Load the Qwen2.5-0.5B base model and serve LoRA adapter responses for unmatched requests. Requires a GPU or sufficient RAM (~2 GB). First /generate call after startup may 503 briefly while the model loads. |
ENABLE_RAG | false | Load the all-MiniLM-L6-v2 sentence encoder and build a per-service semantic index from the mock library. Used for similarity matching in /generate (thresholds: 0.92 = exact replay, 0.75 = grounded generation, below = pure generative). |
GEN_MODEL | Qwen/Qwen2.5-0.5B-Instruct | HuggingFace model ID for the base generative model. Only used when ENABLE_GENERATION=true. |
MOCK_DIR | /data/mocks | Source directory for the mock library. Must match ghost-proxy and ghost-web. |
FAISS_INDEX_PATH | /data/faiss.index | Path to the persisted FAISS vector index file. |
FAISS_MAP_PATH | /data/faiss_id_map.json | Path to the FAISS index-to-mock-ID mapping file. |
API_BASE_URL | http://ghost-web:8000 | Used by the inference server to fetch training data and register adapters. |
ADAPTER_CACHE_SIZE | 3 | Number of LoRA adapters to keep loaded in the LRU cache simultaneously. |
Header redaction
The following headers are always redacted before any traffic is written to disk. This floor cannot be removed or overridden by configuration:
authorization proxy-authorization cookie set-cookie x-api-key x-auth-token x-session-id x-access-token x-user-token x-amz-session-token x-goog-api-key grpc-metadata-authorization api-key
Use REDACT_HEADERS to add your own on top of this floor:
REDACT_HEADERS=x-internal-token,x-customer-id,my-custom-auth
Scrub rules
Scrub rules are configured via the API and apply during the LEARN → MOCK transition. They operate on request and response bodies and query parameters:
# Set global scrub config
PUT /scrub/config
{
"global": {
"headers": ["x-custom-session"],
"query_params": ["trace_id", "debug_token"],
"body_paths": ["$.user.email", "$.payment.card_number"],
"body_patterns": ["\\b[A-Z0-9]{20,}\\b"] // custom regex for tokens
},
"services": {
"payments": {
"body_paths": ["$.card.cvv", "$.card.expiry"]
}
}
}JSONPath expressions ($.field.nested) are used for targeted field removal. Regex patterns are validated at save time — overly broad patterns that would match everything are rejected.
Feature flags by tier
| Feature | Free | Pro | Team |
|---|---|---|---|
| Exact match | ✓ | ✓ | ✓ |
| Chaos injection | ✓ | ✓ | ✓ |
| Per-service mode | ✓ | ✓ | ✓ |
| Smart swap¹ | ✓ | ✓ | ✓ |
| AI inference fallback | ✗ | ✓ | ✓ |
| Generative AI | ✗ | ✓ | ✓ |
| Shared adapters | ✗ | ✗ | ✓ |
| MCP server | ✗ | ✗ | ✓ |
| Team activity log | ✗ | ✗ | ✓ |
| Max services | 1 | ∞ | ∞ |
¹ Smart swap is available on all tiers but must be explicitly enabled via SMART_SWAP_ENABLED=true on the proxy.
Key API endpoints
Mode control
POST /v1/mode # Set global mode: { "mode": "LEARN" | "MOCK" | "PASSTHROUGH" }
GET /v1/mode # Get current mode (reads proxy /health)
# Or switch from the dashboard UI at http://localhost:3000Services (upstreams)
GET /services # List registered upstream services
POST /services # Register a service { name, upstream_url, routing_type, routing_value }
PUT /services/{id} # Update service (including per-service mode override)
DELETE /services/{id} # Remove serviceMock library
GET /mocks # List all mock entries (paginated)
GET /mocks/export # Export (scrubbed_only=true by default)
GET /mocks/unmatched # Requests that had no match in mock mode
GET /mocks/coverage # Coverage stats per endpoint
DELETE /mocks/{id} # Delete a single entry
DELETE /mocks # Clear entire mock libraryTransition (LEARN → MOCK pipeline)
POST /v1/transition/start # Enqueue transition job; returns { job_id }
GET /v1/transition/jobs # List recent jobs
GET /v1/transition/{job_id}/status # Poll progressTraining (Pro+)
POST /training/sessions/{id}/train # Start LoRA fine-tuning
GET /training/sessions/{id}/status # Poll training progress
POST /training/sessions/{id}/activate # Register adapter as activeHealth
GET /health # Proxy health (mode, circuit_breaker_open, version) GET /metrics # Prometheus metrics endpoint