Configuration¶
Every setting is an environment variable, read once at boot. The only required one is the secret key; everything else has a default that is safe on localhost.
Required¶
PRODPEEK_SECRET_KEY |
Encrypts stored credentials, signs the session cookie. prodpeek gen-key. The process refuses to start without it. |
Paths¶
| Default | ||
|---|---|---|
PRODPEEK_DATA_DIR |
data |
Instance state, audit log, proofs, caches |
PRODPEEK_DB |
$DATA/prodpeek.db |
|
PRODPEEK_AUDIT_LOG |
$DATA/audit.jsonl |
|
PRODPEEK_PROFILES_DIR |
unset | An overlay on the bundled catalog. Loads as local, may only narrow |
PRODPEEK_CATALOG_DIR |
unset | Replaces the bundled catalog. Development and testing only |
The policies ship inside the image; there is nothing to mount.
Network¶
| Default | ||
|---|---|---|
PRODPEEK_HOST |
127.0.0.1 |
0.0.0.0 in the container |
PRODPEEK_PORT |
8787 |
Before it leaves localhost¶
| Default | ||
|---|---|---|
PRODPEEK_SESSION_HTTPS_ONLY |
false |
Marks the session cookie Secure. Turn on once TLS is in front |
PRODPEEK_LOGIN_MAX_ATTEMPTS |
10 |
Failed sign-ins per window per address. 0 disables |
PRODPEEK_LOGIN_WINDOW |
300 |
Seconds |
Warning
PRODPEEK_SESSION_HTTPS_ONLY=true with no TLS actually in front means nobody
can sign in. That is the correct failure.
Proving and monitoring¶
| Default | ||
|---|---|---|
PRODPEEK_PROVE_INTERVAL |
3600 |
Seconds between proof runs. 0 disables the schedule |
PRODPEEK_MONITOR_TICK |
5 |
Scheduler tick. 0 disables monitoring |
Metrics¶
| Default | ||
|---|---|---|
PRODPEEK_METRICS |
false |
Serves GET /metrics in Prometheus text format. Off, the path is a 404 |
PRODPEEK_METRICS_PUBLIC |
false |
Drops the admin key requirement, for a scraper on a private network |
With metrics on and public off, /metrics wants an admin key with no project
scope as a bearer. The series and labels are listed under
Endpoints and ports.
The feed and the kill switch¶
All optional. With none of it set, Prodpeek makes no outbound connection and enforces exactly what it always did — deny-by-default is local.
| Default | ||
|---|---|---|
PRODPEEK_CONTROL_URL |
unset | The control plane. Unset means no egress, ever |
PRODPEEK_CHECKIN_INTERVAL |
300 |
|
PRODPEEK_FEED_KEYS |
unset | key_id:base64 pairs whose feeds this instance believes |
PRODPEEK_FEED_FILE |
unset | A signed feed on disk, for air-gapped instances |
PRODPEEK_ON_REVOKED |
block |
Revocation is the only state that blocks by default |
PRODPEEK_ON_STALE |
warn |
|
PRODPEEK_ON_DRIFT |
warn |
block makes a drifted service unavailable |
PRODPEEK_ON_MODIFIED |
warn |
Licence¶
| Default | ||
|---|---|---|
PRODPEEK_LICENSE_ENFORCE |
false |
With it on, an instance past its trial refuses /mcp |
PRODPEEK_LICENSE_KEY |
unset |
The 14-day trial is counted from the first agent call, not from the install:
the first time a client key calls a tool through /mcp, allowed or refused.
Setting up is free. The date is shown under Settings → Instance.
The gate is scoped to /mcp. Console, API, monitoring, incidents and prove keep
working regardless.
Adapters¶
| Default | ||
|---|---|---|
PRODPEEK_SSH_KNOWN_HOSTS |
$DATA/known_hosts |
Where host keys are pinned |
PRODPEEK_SSH_POOL_TTL |
300 |
How long an authenticated connection is reused |
PRODPEEK_GIT_CACHE_DIR |
$DATA/git |
Bare mirrors |
PRODPEEK_GIT_FETCH_TTL |
300 |
How long a mirror is reused before refetching |
The built-in adapters run in-process by default. Setting
PRODPEEK_{SSH,PG,GIT,PROM}_ADAPTER_URL puts one back behind HTTP — same adapter,
same menu, reached over a network instead.
AI¶
Not an environment variable. The provider key is set in the console, under
Settings → AI, and PUT /api/v1/settings refuses it with
secret_not_accepted.
That is deliberate: an agent holding an admin key should not be a courier for your provider key either. Provider, model and base URL are ordinary settings; the key is encrypted at rest and never shown again.
With none configured, Prodpeek makes zero outbound AI calls and loses no functionality.

Extra request headers¶
Not an environment variable — they are per service, set on the add-service form or through the API, and encrypted at rest like the credential.
For upstreams that need more than a token: Grafana Cloud's hosted MCP wants
X-Grafana-URL to say which stack a call is for.
Refused, always: Authorization and Proxy-Authorization (the credential owns
those), Host (it redirects a stored credential at a different server), and the
hop-by-hop headers Connection, Transfer-Encoding, Upgrade, Content-Length,
TE and Trailer. A value containing a newline is refused as header injection.
Logging¶
| Default | ||
|---|---|---|
PRODPEEK_LOG_LEVEL |
info |
warning shows only refusals and errors |
PRODPEEK_ACCESS_LOG |
false |
uvicorn's raw request lines. The decision log is the useful signal |
One readable line per decision: