Self-hosting Configuration
Configure Provon through environment variables on Node and Worker bindings on Cloudflare. Keep non-secret coordinates in version control, keep secret values in a secret manager, and use the same variable names across staging and production.
Critical Secret#
PROVON_AUTH_SECRET is required in production. On Node, PROVON_AUTH_SECRET is an equivalent
fallback read only when PROVON_AUTH_SECRET is unset; Cloudflare Workers bind PROVON_AUTH_SECRET
directly, so set it on every Worker that reads sessions or encrypted credentials.
This value signs authentication state and sessions and derives the key material that encrypts stored OAuth tokens, provider credentials, and Connector secrets. It must be identical across runtimes that read the same metadata store.
Generate at least 32 random bytes:
openssl rand -base64 32Warning
Store and back up PROVON_AUTH_SECRET as encryption key material, separately from encrypted data
backups. Replacing it invalidates sessions and can make existing encrypted credentials
unreadable; rotate it only with a documented credential re-encryption and user
reauthorization plan.
Public Origin And HTTP#
| Variable | Runtime | Purpose |
|---|---|---|
PROVON_HTTP_HOST |
Node | Bind address; defaults to 127.0.0.1 |
PROVON_HTTP_PORT |
Node | Listen port; defaults to 3000 |
PROVON_SERVE_WORKBENCH |
Node | Set to 0 only for an intentional API-only host |
PROVON_TRUST_PROXY_HEADERS |
Node | true to accept proxy-written X-Forwarded-Proto/Host/Port; otherwise those headers are stripped |
PROVON_AUTH_ORIGIN |
Both | Exact public origin used for OAuth callbacks |
PROVON_WORKBENCH_ORIGINS |
Both | Comma-separated exact browser origins allowed to call the API |
PROVON_MCP_PUBLIC_ORIGINS |
Cloudflare MCP | Comma-separated browser origins allowed to reach the MCP Worker |
PROVON_AUTH_COOKIE_DOMAIN |
Both | Shared parent cookie domain for split subdomains |
PROVON_AUTH_TRUST_HOST |
Both | Trust forwarded public host behind a trusted proxy when true |
PROVON_VERSION |
Both | Version reported by /healthz |
Same-origin Node example:
PROVON_AUTH_ORIGIN=https://provon.example.com
PROVON_WORKBENCH_ORIGINS=https://provon.example.com
PROVON_TRUST_PROXY_HEADERS=true
PROVON_AUTH_TRUST_HOST=trueSplit Cloudflare origins:
PROVON_AUTH_ORIGIN=https://api.provon.example
PROVON_WORKBENCH_ORIGINS=https://app.provon.example
PROVON_AUTH_COOKIE_DOMAIN=.provon.example
PROVON_AUTH_TRUST_HOST=trueOnly trust forwarded hosts when the ingress removes client-supplied forwarding headers and
writes its own values. Forwarded origins that do not exactly match PROVON_AUTH_ORIGIN are
ignored.
Node Storage#
| Variable | Default | Purpose |
|---|---|---|
PROVON_META_DB_URL |
libsql:.provon/data/meta.db |
Metadata database URL |
PROVON_META_DB_AUTH_TOKEN |
None | Remote metadata libSQL authentication |
PROVON_METERING_DB_URL |
libsql:.provon/data/metering.db |
Usage-event database URL |
PROVON_METERING_DB_AUTH_TOKEN |
None | Remote usage-event libSQL authentication |
PROVON_JOBS_DB_URL |
libsql:.provon/data/jobs.db |
Background job queue database URL |
PROVON_JOBS_DB_AUTH_TOKEN |
None | Remote jobs libSQL authentication |
PROVON_GATEWAY_DB_URL |
libsql:.provon/data/gateway.db |
Gateway usage and target state database URL |
PROVON_GATEWAY_DB_AUTH_TOKEN |
None | Remote Gateway libSQL authentication |
PROVON_TELEMETRY_DB_URL |
duckdb:.provon/data/telemetry.duckdb |
Local DuckDB telemetry database path |
PROVON_TELEMETRY_READ_CONNECTIONS |
CPU count, capped at 4 | Concurrent DuckDB read connections per telemetry database |
PROVON_TELEMETRY_TENANT_ISOLATION |
organization |
organization isolates telemetry per project organization; shared relaxes the boundary |
PROVON_BLOBS_DIR |
.provon/blobs |
Blobs, staged payloads, and runtime data root |
Metadata, usage events, jobs, and Gateway state must use distinct database URLs; sharing one
file between them reunites the writers each database exists to separate. The directory
holding PROVON_BLOBS_DIR also holds persistent Node runtime state: mount and back up the
parent data directory, not only the visible blob files.
Cloudflare Telemetry#
| Variable or binding | Purpose |
|---|---|
PROVON_TELEMETRY_BACKEND |
Must be cloudflare-r2-sql on Worker deployments |
PROVON_R2_SQL_ACCOUNT_ID |
Cloudflare account containing telemetry |
PROVON_R2_SQL_BUCKET |
Data Catalog-enabled telemetry bucket |
PROVON_R2_SQL_NAMESPACE |
Base R2 SQL namespace |
PROVON_R2_SQL_TOKEN |
R2 SQL API token secret, on reader Workers only |
PROVON_R2_CATALOG_URI |
Iceberg REST catalog URI for the warehouse runtime |
PROVON_R2_CATALOG_WAREHOUSE |
Data Catalog warehouse name |
PROVON_R2_DATA_CATALOG_TOKEN |
Read-write catalog token for telemetry mutations, on the warehouse only |
PROVON_TELEMETRY_WAREHOUSE_CACHE_MAX_TABLES |
Per-container table runtimes retained in memory; defaults to 256 |
PROVON_BLOB_BUCKET |
R2 binding for staging and blobs |
PROVON_TELEMETRY_WAREHOUSE_EXECUTOR |
Internal Service Binding for telemetry mutations |
Default read-model variables in the checked-in templates:
PROVON_TELEMETRY_QUERY_SOURCE = "summaries"
PROVON_TELEMETRY_PAYLOAD_RETENTION = "all"PROVON_TELEMETRY_QUERY_SOURCE:summaries(default) reads trace summaries;append-only-spansreads raw spans.summariesrequires thePROVON_TELEMETRY_SUMMARY_QUEUEbinding on writer deployments.PROVON_TELEMETRY_PAYLOAD_RETENTION:all(default) keeps raw payload fields;projected-onlydrops raw payload fields at the telemetry write boundary. Chooseprojected-onlyonly when projected evidence is sufficient for investigation and diagnosis.
Use the checked-in wrangler.*.example.toml files as the binding contract; do not rename a
binding without changing the corresponding runtime code.
OTLP And Background Work#
Defaults suit development and moderate workloads. Tune only from measured body sizes, queue lag, write latency, and dependency limits.
| Variable | Default | Purpose |
|---|---|---|
PROVON_OTLP_MAX_BYTES |
10485760 |
Decoded HTTP payload ceiling |
PROVON_OTLP_MAX_BATCH_BYTES |
16777216 |
Soft bytes claimed per ingest tick |
PROVON_OTLP_MAX_JOB_BYTES |
16777216 |
Hard ceiling for one staged job |
PROVON_OTLP_WORKER_INTERVAL_MS |
250 |
Node ingest worker interval; 0 disables it |
PROVON_OTLP_WORKER_BATCH_SIZE |
50 |
Jobs claimed per Node tick |
PROVON_OTLP_WORKER_LOCK_MS |
60000 |
Ingest claim lease |
PROVON_OTLP_FLUSH_MAX_ROWS |
2000 |
Soft rows per write group |
PROVON_OTLP_FLUSH_MAX_BYTES |
8388608 |
Soft bytes per write group |
PROVON_OTLP_MAX_PENDING_JOBS |
10000 |
Admission ceiling for queued ingest |
PROVON_OTLP_CLEANUP_INTERVAL_MS |
3600000 |
Completed-job cleanup interval |
PROVON_OTLP_CLEANUP_OLDER_THAN_MS |
86400000 |
Completed-job age before cleanup |
Additional Node background controls:
| Variable | Default | Purpose |
|---|---|---|
PROVON_TELEMETRY_SUMMARY_MATERIALIZATION_INTERVAL_MS |
5000 |
Trace-summary materialization drain interval |
PROVON_DIAGNOSTICS_INTERVAL_MS |
1000 |
Conversation-analysis and diagnostic Run interval |
PROVON_DIAGNOSTICS_BATCH_SIZE |
100 |
Conversation-analysis jobs claimed per tick |
PROVON_FINDING_WORK_ITEM_SYNC_INTERVAL_MS |
300000 |
External repair work-item status sync interval |
Gateway usage reservation reconciliation runs only on the Node loop:
| Variable | Default | Purpose |
|---|---|---|
PROVON_GATEWAY_USAGE_RECONCILIATION_ENABLED |
Enabled | Disable stale usage-policy reconciliation |
PROVON_GATEWAY_USAGE_RECONCILIATION_INTERVAL_MS |
60000 |
Usage-policy cleanup loop interval |
PROVON_GATEWAY_USAGE_STALE_RESERVATION_MS |
600000 |
Usage-policy reservation age threshold |
PROVON_GATEWAY_USAGE_RECONCILIATION_BATCH_SIZE |
100 |
Reservations released per tick |
Setting an interval to 0 disables a loop only where the implementation accepts a
non-negative interval. Disabling a loop is an architecture change: assign its responsibility
to another runtime before doing so.
Data Retention#
Project retention policy selects what expires. Runtime variables control the Node maintenance job:
| Variable | Default | Purpose |
|---|---|---|
PROVON_DATA_RETENTION_INTERVAL_MS |
21600000 |
Node retention interval |
PROVON_DATA_RETENTION_BATCH_SIZE |
10 |
Projects or organizations per run |
PROVON_DATA_RETENTION_DELETE_TIMEOUT_MS |
60000 |
Delete timeout |
PROVON_DATA_RETENTION_MAX_RETRIES |
3 |
Retry count |
PROVON_DATA_RETENTION_DELETE_MAX_FILES |
128 |
Iceberg files deleted per bounded operation |
On Cloudflare, retention runs inside the Maintenance Worker cron (0 */6 * * *) alongside
metadata maintenance and work-item sync. R2 lifecycle rules, snapshot expiration, and
compaction are separate platform controls configured with the telemetry-maintenance script;
see Operations.
Sign-in Providers#
Email and password sign-in remains available when no social provider is configured. A social provider is enabled only when both its client ID and client secret are present.
| Provider | Required variables | Optional |
|---|---|---|
| GitHub | AUTH_GITHUB_CLIENT_ID, AUTH_GITHUB_CLIENT_SECRET |
None |
AUTH_GOOGLE_CLIENT_ID, AUTH_GOOGLE_CLIENT_SECRET |
None | |
| Apple | AUTH_APPLE_CLIENT_ID, AUTH_APPLE_CLIENT_SECRET |
AUTH_APPLE_ALLOW_ACCOUNT_LINKING |
Register:
https://<api-origin>/auth/callback/github
https://<api-origin>/auth/callback/google
https://<api-origin>/auth/callback/appleGoogle and GitHub identities require verified provider email claims. Link another identity from an authenticated Account settings → Sign-in methods page; anonymous email-based account linking is not supported.
Enterprise OIDC#
Required:
AUTH_OIDC_CLIENT_IDAUTH_OIDC_CLIENT_SECRETAUTH_OIDC_ISSUERorAUTH_OIDC_WELL_KNOWN
Optional controls include AUTH_OIDC_NAME, AUTH_OIDC_SCOPE,
AUTH_OIDC_TOKEN_ENDPOINT_AUTH_METHOD, AUTH_OIDC_ALLOW_ACCOUNT_LINKING, and
AUTH_OIDC_EMAIL_TRUST_POLICY. The default email trust policy requires email_verified=true;
use trusted_provider only when the IdP contract guarantees email ownership. The callback
provider ID is enterprise-oidc:
https://<api-origin>/auth/callback/enterprise-oidcConnector OAuth#
Login OAuth and Connector OAuth are separate applications. Connector credentials use the
*_INTEGRATION_* prefix.
| Connector | Required variables | Optional scope override |
|---|---|---|
| GitHub | GITHUB_INTEGRATION_CLIENT_ID, GITHUB_INTEGRATION_CLIENT_SECRET |
GITHUB_INTEGRATION_SCOPES |
| GitLab | GITLAB_INTEGRATION_CLIENT_ID, GITLAB_INTEGRATION_CLIENT_SECRET |
GITLAB_INTEGRATION_SCOPES |
| Jira | JIRA_INTEGRATION_CLIENT_ID, JIRA_INTEGRATION_CLIENT_SECRET |
JIRA_INTEGRATION_SCOPES |
| Linear | LINEAR_INTEGRATION_CLIENT_ID, LINEAR_INTEGRATION_CLIENT_SECRET |
LINEAR_INTEGRATION_SCOPES |
Register:
https://<api-origin>/v1/integrations/github/callback
https://<api-origin>/v1/integrations/gitlab/callback
https://<api-origin>/v1/integrations/jira/callback
https://<api-origin>/v1/integrations/linear/callbackSee Connectors for project setup and default scopes.
Configuration Review#
Important
Before production: compare staging and production variable names without comparing secret
values; confirm every runtime reading one metadata store shares the same PROVON_AUTH_SECRET;
verify exact Workbench origins and public callback URLs; point storage paths or bindings at
durable production resources; keep body, queue, and retention limits consistent across
producer and consumer deployments; restart or redeploy affected deployments after a shared
secret or binding change; and record the configuration version with the application release.