openvibers/openvibe.events .env.example
.env.example
| 1 | # ═══════════════════════════════════════════════════════════════ |
| 2 | # OpenVibe.Events — Environment Configuration |
| 3 | # Copy to .env and fill in values. |
| 4 | # In production this lives at /etc/openvibe/events.env (0600); the systemd unit sets |
| 5 | # NODE_ENV and PORT itself. |
| 6 | # ═══════════════════════════════════════════════════════════════ |
| 7 | |
| 8 | # Server |
| 9 | PORT=4300 |
| 10 | HOST=127.0.0.1 |
| 11 | NODE_ENV=development |
| 12 | # The API origin (plan T7): everything Events names about itself — Location headers, realtime URLs, |
| 13 | # limits.json links, llms.txt/sitemap, the home's examples — uses it; defaults to https://openvibe.events |
| 14 | # in production, to http://localhost:PORT otherwise. |
| 15 | #BASE_URL=https://openvibe.events |
| 16 | # The product origin; defaults to BASE_URL (openvibe.events is the API and product origin, plan T7). |
| 17 | #EVENTS_SITE_URL=https://openvibe.events |
| 18 | |
| 19 | # IndexNow (openvibe-shared/indexnow): a key makes search engines recrawl the product home and its |
| 20 | # crawl files when they change (a release). 8–128 hex/alphanumeric characters; the key file is served |
| 21 | # at /<key>.txt. Unset = off, no key file, nothing sent. |
| 22 | #INDEXNOW_KEY= |
| 23 | |
| 24 | # Identity — OpenVibe.Network signs service tokens (client_credentials, audience |
| 25 | # openvibe.events) and user JWTs. The public key is fetched from |
| 26 | # <url>/api/.well-known/jwks (internal URL first), retried every 30 s until it loads. |
| 27 | OV_NETWORK_URL=https://openvibe.network |
| 28 | OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000 |
| 29 | # Expected `iss` of every token (defaults to OV_NETWORK_URL). |
| 30 | #OV_NETWORK_ISSUER=https://openvibe.network |
| 31 | # Pin the key instead of fetching it (PEM; \n escapes allowed). |
| 32 | #OV_NETWORK_PUBLIC_KEY= |
| 33 | # A browser's user JWT is accepted when its aud contains one of these. |
| 34 | #EVENTS_USER_AUDIENCES=openvibe.events,openvibe.network |
| 35 | |
| 36 | # PostgreSQL (ADR-035), written by OpenVibe.Host roles/data/add-service.sh events: the runtime role through PgBouncer, |
| 37 | # the owner on a direct connection (migrations), and Valkey (shared limit counters). |
| 38 | # Without DATABASE_URL, development uses an embedded PGlite database in data/pglite. |
| 39 | DATABASE_URL= |
| 40 | DATABASE_DIRECT_URL= |
| 41 | VALKEY_URL= |
| 42 | VALKEY_PREFIX= |
| 43 | # Optional NATS (deploy/nats/nats-server.conf): nats-v1, cross-process SSE fan-out (the TOPIC carrier), and nats-js-v1, |
| 44 | # JetStream (the STREAM carrier, needs nats-server -js). nats://[user:pass@]host:4222 on loopback or the private network; |
| 45 | # unset, nothing connects and pg-v1/valkey-v1 carry TOPIC, pg-v1 STREAM. EVENTS_CARRIERS_DISABLED=nats-v1 or nats-js-v1 |
| 46 | # rolls one back; NATS_JETSTREAM=off leaves nats-js-v1 out. |
| 47 | #NATS_URL= |
| 48 | #NATS_SUBJECT_PREFIX=ov.events. |
| 49 | #NATS_JETSTREAM= |
| 50 | #NATS_STREAM=OV_EVENTS_STREAM |
| 51 | # Optional cloud queue (ADR-042 decision 5): cloud-v1, a QUEUE-only push carrier that POSTs { event_id, subscription_id } |
| 52 | # as an SQS SendMessage to a CLOUD_QUEUE_URL endpoint, SigV4-signed (node:crypto, no dependency). Credentials may be |
| 53 | # omitted for a local endpoint; CLOUD_QUEUE_PREFIX is an optional path prefix under the URL. Off unless the URL is set; |
| 54 | # EVENTS_CARRIERS_DISABLED=cloud-v1 rolls it back and pg-v1/valkey-v1 carries QUEUE. Its rate card (rc-cloud-queue-v1) is |
| 55 | # not written until the owner sets its price: unpriced, the planner never prefers it. |
| 56 | #CLOUD_QUEUE_URL= |
| 57 | #CLOUD_QUEUE_REGION=us-east-1 |
| 58 | #CLOUD_QUEUE_PREFIX= |
| 59 | #CLOUD_QUEUE_ACCESS_KEY= |
| 60 | #CLOUD_QUEUE_SECRET_KEY= |
| 61 | #EVENTS_CARRIERS=pg-v1,valkey-v1,nats-v1,nats-js-v1,cloud-v1 |
| 62 | #EVENTS_CARRIERS_DISABLED= |
| 63 | # Retention in tiers (ADR-042 decision 8; README "Retention: three tiers"). Hot events (and their deliveries) older |
| 64 | # than this move to the replay tier (events_archive) at the hourly prune. |
| 65 | EVENTS_RETENTION_DAYS=30 |
| 66 | # Days (from receipt) an event stays readable from the replay tier: pulls, SSE resume and by-id reads; resuming from |
| 67 | # before it yields a gap. 0 = no replay tier: old events are deleted, as before, and events_archive is emptied. |
| 68 | EVENTS_REPLAY_RETENTION_DAYS=365 |
| 69 | # The archive tier, operator only (node scripts/events-archive.js export|restore --month YYYY-MM): a local directory, |
| 70 | # or an S3-compatible bucket when EVENTS_ARCHIVE_S3_BUCKET is set (path-style, https; SigV4, no dependency). |
| 71 | #EVENTS_ARCHIVE_DIR=/var/lib/openvibe/events-archive |
| 72 | #EVENTS_ARCHIVE_S3_ENDPOINT=https://s3.example.com |
| 73 | #EVENTS_ARCHIVE_S3_BUCKET= |
| 74 | #EVENTS_ARCHIVE_S3_REGION=us-east-1 |
| 75 | #EVENTS_ARCHIVE_S3_ACCESS_KEY_ID= |
| 76 | #EVENTS_ARCHIVE_S3_SECRET_ACCESS_KEY= |
| 77 | #EVENTS_ARCHIVE_S3_PREFIX=events/ |
| 78 | # Accepted event ids are remembered this long, so late re-publishes stay duplicates. |
| 79 | EVENTS_RECEIPT_RETENTION_DAYS=90 |
| 80 | #EVENTS_PRUNE_INTERVAL_MS=3600000 |
| 81 | |
| 82 | # Publishing |
| 83 | #EVENTS_MAX_PAYLOAD_BYTES=65536 |
| 84 | # A trace may carry this many hops before a publish is refused (events.loop_detected). |
| 85 | #EVENTS_MAX_HOPS=8 |
| 86 | # Which source may publish which event_type prefixes. JSON; replaces the default, which is |
| 87 | # { "<source>": ["<source>."] } for live media network community chat openre billing tips vip |
| 88 | # ai games tools codes host sources search wiki blog news reviews deals coupons trade bot. Every prefix |
| 89 | # must start with "<source>."; "app" and "app-*" are reserved for developer apps. |
| 90 | #EVENTS_SOURCE_PREFIXES={"live":["live."],"media":["media."]} |
| 91 | # Network-wide prefixes any first-party service may publish (default: provider., provider health |
| 92 | # and capacity telemetry). Comma-separated; a prefix's first segment must not be a source. |
| 93 | #EVENTS_SHARED_PREFIXES=provider. |
| 94 | |
| 95 | # Delivery worker |
| 96 | #EVENTS_WORKER=on |
| 97 | #EVENTS_WORKER_INTERVAL_MS=500 |
| 98 | #EVENTS_MAX_INFLIGHT=20 |
| 99 | # Of which developer-app deliveries may use at most (default: half of EVENTS_MAX_INFLIGHT) |
| 100 | #EVENTS_APP_MAX_INFLIGHT=10 |
| 101 | #EVENTS_DELIVERY_TIMEOUT_MS=10000 |
| 102 | #EVENTS_MAX_ATTEMPTS=8 |
| 103 | #EVENTS_BACKOFF_MS=1000,5000,30000,120000,600000,3600000 |
| 104 | # /api/ready lists `dlq` as degraded (the service stays ready) above this many dead deliveries. |
| 105 | #EVENTS_DLQ_DEGRADED_AT=100 |
| 106 | #EVENTS_MAX_SUBSCRIPTIONS=100 |
| 107 | # Hostnames a subscription endpoint may use (SSRF guard). `*.openvibe.*` = openvibe.<tld> |
| 108 | # and its subdomains; IP literals only when listed exactly. |
| 109 | #EVENTS_ENDPOINT_HOSTS=127.0.0.1,*.openvibe.* |
| 110 | |
| 111 | # Project usage (WS-N task 4): each closed hour of a developer project's publishing and webhook |
| 112 | # deliveries becomes one events.usage.recorded event per capability and environment, delivered to |
| 113 | # Network (the project dashboard on openvibe.services). off = nothing counted or sent. |
| 114 | #EVENTS_USAGE=on |
| 115 | #EVENTS_USAGE_FLUSH_MS=300000 |
| 116 | |
| 117 | # Billing readings (plan T5 step 14, docs/cutover-events-billing-readings.md): each closed hour's queue operations per |
| 118 | # production project (metric queue-operation-64kb) become one platform.usage-sample@1 reading posted to Billing |
| 119 | # (billing.usage.record; the Network client `events` needs that grant). 0 = off. Without the URL or the secret the |
| 120 | # readings are stored and stay queued. |
| 121 | #EVENTS_BILLING_INTERVAL_MS=0 |
| 122 | #OV_BILLING_INTERNAL_URL=http://127.0.0.1:4600 |
| 123 | #OV_OAUTH_CLIENT_ID=events |
| 124 | #OV_OAUTH_CLIENT_SECRET= |
| 125 | # The account export and deletion consumer (ADR-033): Events' own subscription to the two account topics, delivered |
| 126 | # back to POST /internal/events. Unset: the route is off and the account events do not reach Events. The secret is 32 |
| 127 | # characters or more; it is the one Events signs its own deliveries with. |
| 128 | #EVENTS_EVENTS_URL=https://openvibe.events |
| 129 | #EVENTS_EVENTS_SECRET= |
| 130 | # GitHub webhooks in (AL5: server/github.js): the secret GitHub signs deliveries with (repo Settings → |
| 131 | # Webhooks → the webhook's Secret; 16 characters or more, comma-separated while rotating). Unset: POST |
| 132 | # /api/v1/in/github answers 404 and no github.* event is ever stored. |
| 133 | #EVENTS_GITHUB_WEBHOOK_SECRET= |
| 134 | #OV_BILLING_AUDIENCE=openvibe.billing |
| 135 | #OV_BILLING_TIMEOUT_MS=10000 |
| 136 | |
| 137 | # Developer apps (events.app.publish|read|subscribe, ADR-014). App subscriptions must use public |
| 138 | # https endpoints (no allow-list; checked at subscribe and delivery time). Quotas are per project |
| 139 | # and environment; 0 turns a limit off. EVENTS_APPS=off disables the app paths. |
| 140 | #EVENTS_APPS=on |
| 141 | #EVENTS_APP_PUBLISH_PER_MINUTE=120 |
| 142 | #EVENTS_APP_RETAINED_BYTES=52428800 |
| 143 | #EVENTS_APP_MAX_SUBSCRIPTIONS=20 |
| 144 | #EVENTS_APP_SANDBOX_PUBLISH_PER_MINUTE=30 |
| 145 | #EVENTS_APP_SANDBOX_RETAINED_BYTES=5242880 |
| 146 | #EVENTS_APP_SANDBOX_MAX_SUBSCRIPTIONS=5 |
| 147 | #EVENTS_APP_SANDBOX_RETENTION_DAYS=7 |
| 148 | |
| 149 | # Per-actor limits (server/actor-limits.js): requests one principal (svc:…, app:app_…) may make to a |
| 150 | # read route per minute and per hour; past them 429 rate_limited with Retry-After. Publishing, |
| 151 | # subscriptions and replay have their own numbers (README). Never on health, ready, metrics. |
| 152 | # EVENTS_LIMITS=off turns them all off (a rollback lever). |
| 153 | #EVENTS_LIMITS=on |
| 154 | #EVENTS_LIMITS_MINUTE=120 |
| 155 | #EVENTS_LIMITS_HOUR=3000 |
| 156 | |
| 157 | # Realtime (SSE) gateway |
| 158 | #REALTIME_MAX_CONNECTIONS=2000 |
| 159 | #REALTIME_MAX_TOPICS=20 |
| 160 | #REALTIME_HEARTBEAT_MS=25000 |
| 161 | #REALTIME_REPLAY_MAX=1000 |
| 162 | # A browser resuming with Last-Event-ID is replayed public events received this recently only |
| 163 | # (0: none); older public events come as `event: gap` (reason public_window). Subject events |
| 164 | # addressed to the viewer, and service viewers, keep the whole retention. |
| 165 | #REALTIME_PUBLIC_REPLAY_SECONDS=300 |
| 166 | # Signed-out browsers may receive public events. |
| 167 | #REALTIME_ALLOW_ANONYMOUS=true |
| 168 | # Exact extra CORS origins besides https://*.openvibe.* (development). |
| 169 | #REALTIME_CORS_ORIGINS=http://localhost:3000 |
| 170 |