Skip to content

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.

View as Markdown Open the plain-text version of this page.

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:

bash
openssl rand -base64 32

Warning

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:

bash
PROVON_AUTH_ORIGIN=https://provon.example.com
PROVON_WORKBENCH_ORIGINS=https://provon.example.com
PROVON_TRUST_PROXY_HEADERS=true
PROVON_AUTH_TRUST_HOST=true

Split Cloudflare origins:

bash
PROVON_AUTH_ORIGIN=https://api.provon.example
PROVON_WORKBENCH_ORIGINS=https://app.provon.example
PROVON_AUTH_COOKIE_DOMAIN=.provon.example
PROVON_AUTH_TRUST_HOST=true

Only 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:

toml
PROVON_TELEMETRY_QUERY_SOURCE = "summaries"
PROVON_TELEMETRY_PAYLOAD_RETENTION = "all"
  • PROVON_TELEMETRY_QUERY_SOURCE: summaries (default) reads trace summaries; append-only-spans reads raw spans. summaries requires the PROVON_TELEMETRY_SUMMARY_QUEUE binding on writer deployments.
  • PROVON_TELEMETRY_PAYLOAD_RETENTION: all (default) keeps raw payload fields; projected-only drops raw payload fields at the telemetry write boundary. Choose projected-only only 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
Google AUTH_GOOGLE_CLIENT_ID, AUTH_GOOGLE_CLIENT_SECRET None
Apple AUTH_APPLE_CLIENT_ID, AUTH_APPLE_CLIENT_SECRET AUTH_APPLE_ALLOW_ACCOUNT_LINKING

Register:

text
https://<api-origin>/auth/callback/github
https://<api-origin>/auth/callback/google
https://<api-origin>/auth/callback/apple

Google 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_ID
  • AUTH_OIDC_CLIENT_SECRET
  • AUTH_OIDC_ISSUER or AUTH_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:

text
https://<api-origin>/auth/callback/enterprise-oidc

Connector 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:

text
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/callback

See 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.