# ═══════════════════════════════════════════════════════════════ # openvibe.network — Environment Configuration # Copy to .env and fill in values. No secrets belong in this file. # Production env lives at /etc/openvibe/network.env (mode 0600). # ═══════════════════════════════════════════════════════════════ # Server PORT=4000 HOST=0.0.0.0 NODE_ENV=development BASE_URL=http://localhost:4000 OV_NETWORK_URL=http://localhost:4000 OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000 OV_NETWORK_LOGIN_URL=http://localhost:4000 # IndexNow (openvibe-shared/indexnow): 8–128 letters or digits. Set, the key file answers at # /.txt; unset, it is off and nothing is served. The key goes in /etc/openvibe/network.env only. INDEXNOW_KEY= # Per-actor limits on API writes by a person's session (server/auth/actor-limits.js, roadmap WS-R task 4), # per minute and per hour; account, project, theme, avatar, follow and block writes have tighter numbers of their own. #NETWORK_LIMITS_MINUTE=120 #NETWORK_LIMITS_HOUR=3000 # Sign in on another device (server/auth/qr-signin.js): a QR on one device, a scan on another and a two-digit match. # Off unless this is explicitly on; off means /auth/qr/* and /q are not mounted. # NETWORK_QR_SIGNIN=1 # Security — CHANGE THESE IN PRODUCTION # /internal/* takes capability-scoped service tokens; the shared internal key is retired (plan T2). SETUP_TOKEN=change-me-to-a-second-random-secret BOOTSTRAP_PROFILE=local-dev # Project secrets (ADR-056, server/developer/secrets.js): 32 random bytes, base64 or hex (openssl rand -base64 32). # Unset = project secrets are off (503 secrets.unavailable). Changing it makes every stored secret unreadable. # NETWORK_SECRETS_KEY= # Developer projects (docs/developer-projects.md) # Audiences that accept sandbox app tokens, comma-separated. Leave it UNSET for the code default # (openvibe.media,openvibe.events,openvibe.tools); set it to an empty value to accept none. # DEV_SANDBOX_AUDIENCES=openvibe.media,openvibe.events,openvibe.tools,openvibe.services,openvibe.ai,openvibe.quest,openvibe.play # Public capabilities every project's SANDBOX apps may hold without staff, comma-separated. Leave it # UNSET for the code default (media.object.upload/read, events.app.publish/read/subscribe, # tools.job.create/read/cancel; ids the installed contracts do not define are skipped); empty = none. # Production apps only ever use the staff-set project allowance. # DEV_SANDBOX_ALLOWANCE=media.object.upload,media.object.read,events.app.publish,events.app.read,events.app.subscribe,tools.job.create,tools.job.read,tools.job.cancel # Seconds a rotated client secret keeps working (0..604800; default 86400) DEV_CREDENTIAL_OVERLAP_S=86400 # Public capabilities every new project's allowance starts with, comma-separated. Empty = staff grant each one. DEV_DEFAULT_ALLOWANCE= DEV_MAX_PROJECTS_PER_OWNER=10 DEV_MAX_APPS_PER_PROJECT=20 # First-party services (OAuth client ids) that may host a project member's agents, comma-separated # (docs/t2-projects-and-grants.md). Leave it UNSET for the code default (actor); empty = none. # AGENT_HOST_SERVICES=actor # OpenVibe.Events base URL for relaying developer-project events (network.app.*, network.credential.*, # network.grant.changed). Unset = no relay (events stay in dev_audit and are backfilled once it is set). # OV_EVENTS_INTERNAL_URL=http://127.0.0.1:4300 # Admin account auto-created on first run ADMIN_USERNAME=admin ADMIN_PASSWORD=change-me # Owner account (gates owner-only admin areas: Deploy, SSH, secrets) OWNER_USERNAME= # PostgreSQL (ADR-035, plan T2), written by OpenVibe.Host roles/data/add-service.sh network: the runtime # role through PgBouncer, the owner on a direct connection (migrations), and Valkey (shared limit counters). # Without DATABASE_URL, development uses an embedded PGlite database in data/pglite (PGLITE_DIR overrides it); # production refuses to boot. DATABASE_URL= DATABASE_DIRECT_URL= VALKEY_URL= #VALKEY_PREFIX=ov:network: # Paths (relative to project root) DATA_DIR=data AVATAR_PATH=data/avatars JWT_PRIVATE_KEY=data/keys/private.pem JWT_PUBLIC_KEY=data/keys/public.pem # Public service URLs (defaults shown; override for local dev / white-label) #OV_LIVE_URL=https://openvibe.live #OV_TOOLS_URL=https://openvibe.tools #OV_GAMES_URL=https://openvibe.games #OV_MEDIA_URL=https://openvibe.media # Connected services (internal, not proxied through Cloudflare) OV_LIVE_INTERNAL_URL=http://127.0.0.1:3000 OV_TOOLS_INTERNAL_URL=http://127.0.0.1:4001 OV_GAMES_INTERNAL_URL=http://127.0.0.1:8000 OV_MEDIA_INTERNAL_URL=http://127.0.0.1:4100 OV_CHAT_INTERNAL_URL=http://127.0.0.1:4400 # OpenVibe.Mail: the account home's Receipts card reads the person's own receipt summaries here. OV_MAIL_INTERNAL_URL=http://127.0.0.1:5250 # The publication reviewer queue (/admin/review): each product's staff review-queue endpoint. OV_WIKI_INTERNAL_URL=http://127.0.0.1:4800 OV_BLOG_INTERNAL_URL=http://127.0.0.1:4810 OV_NEWS_INTERNAL_URL=http://127.0.0.1:4820 OV_TRADE_INTERNAL_URL=http://127.0.0.1:4860 # Optional: SSH admin-tab context (non-secret display values) #SSH_SERVER_HOST= #SSH_PROJECTS_ROOT=/opt/openvibe.network /opt/openvibe.live # openvibe.my is Network's own first-party OAuth client 'my' (redirect https://openvibe.my/auth/callback). # The client row and its secret are seeded in oauth_clients and read from there at boot; nothing needs setting. # To change the secret, rotate the row (setup/service-principal.js rotate my, WITHOUT --write-env) and restart. #OV_MY_OAUTH_CLIENT_ID=my #OV_MY_OAUTH_CLIENT_SECRET= #OV_MY_URL=https://openvibe.my # ═══════════════════════════════════════════════════════════════ # Provider secrets (server/secrets.js). Each one is read from its variable first; the admin # panel's database copy is only a fallback, and the panel cannot change one set here. In # production put them in /etc/openvibe/network.env; scripts/secrets-out-of-db.js then blanks # the database copies (README "Provider secrets"). # ═══════════════════════════════════════════════════════════════ #RESEND_API_KEY= #RESEND_WEBHOOK_SECRET= #DISCORD_BOT_TOKEN= #DISCORD_OAUTH_CLIENT_SECRET= #VAPID_PRIVATE_KEY= #VAPID_PUBLIC_KEY= (optional: derived from VAPID_PRIVATE_KEY) # ═══════════════════════════════════════════════════════════════ # Email Notifications (optional) # # From-addresses are managed through the admin panel; the Resend API key is RESEND_API_KEY # above (or, as a fallback, the admin panel). # ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════ # Notifications # ═══════════════════════════════════════════════════════════════ # Enable/disable the notification system globally NOTIFICATIONS_ENABLED=true # Days to keep old notifications before cleanup (default: 30) NOTIFICATION_MAX_AGE_DAYS=30 # Only send emails for CRITICAL priority notifications (recommended) NOTIFICATION_EMAIL_CRITICAL_ONLY=true # ═══════════════════════════════════════════════════════════════ # RSA Key Generation (run once during setup): # # mkdir -p data/keys # openssl genrsa -out data/keys/private.pem 2048 # openssl rsa -in data/keys/private.pem -pubout -out data/keys/public.pem # # The private key stays on openvibe.network only. Other services verify # tokens OFFLINE via the JWKS endpoint (/api/.well-known/jwks). # ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════ # OpenVibe Link on Android (server/auth/app-links.js) # ═══════════════════════════════════════════════════════════════ # The SHA-256 fingerprints of the certificate that signs the RELEASE build of network.openvibe.link, comma-separated, # colon-hex (AA:BB:…). They are what /.well-known/assetlinks.json publishes so Android hands the https:// # openvibe.network/link/auth sign-in return to the app alone; the certificates are public values, not secrets. # # Leave it unset until the owner's release key exists. With no fingerprint, Android verifies nothing, /link/auth opens # this site's page, and OpenVibe Link gets the extension's read-only Dock token instead of a session. # LINK_ANDROID_CERT_SHA256=AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99