Commits
-
Events: iovalkey is a dependency, test:pg boots with Valkey, drain() waits for mid-pass completions.OpenVibers · 28 Sept 2026
7bccceb -
Events on PostgreSQL (ADR-035, roadmap WS-X2, repository pass G3).OpenVibers · 28 Sept 2026
f71906e -
npm test no longer counts a skipped test as passed (roadmap WS-Q task 7; openvibe-shared/test-runner, Shared v1.25.0). test/run.js counted every file that exited 0 as passed, so a file that printed that it skipped its work and checked nothing still read as green. It is now the shared runner (same files, one at a time as before, 60 s timeout per file): a test prints "<label>: skipped (<why>)" for what it could not run, and that file is listed with ○ and its reasons and not counted as passed; --strict makes a skip fail the run. No test here skips anything. openvibe-shared is pinned at v1.25.0 (from v1.22.0; 1.23 and 1.24 add the web runtime, release-watch fixes and the readiness skip, and /api/ready answers as before because its db check really runs). npm test (Node 22) 18/18.OpenVibers · 28 Sept 2026
7c575cd -
README and STATUS.json are current (roadmap WS-U task 3): the README gains Capabilities (the seven implemented capabilities; Events calls no service with a grant; events.usage.recorded), Security (SECURITY.md, auth, private data, egress, delivery signatures, exposure and ticket-free logs) and Deploy (sudo ovhost deploy events, unit, port, env file, store, vhost, drain, rollback) sections. The status line no longer says Media reports only over Live's webhook or that no browser uses the realtime stream, and the contracts note names the v0.63.0 pin. STATUS.json names openvibe-contracts v0.63.0, gains features and is updated 2026-09-28.OpenVibers · 28 Sept 2026
19919ec -
Deliveries carry only the v2 signature (shim C-60 retired). The v1 header, X-OpenVibe-Signature, was an HMAC of the body with no timestamp and so replayable, and it is no longer sent. Checked on 2026-09-28: every consumer in production verifies v2 (openvibe-sdk parseDelivery with requireV2, or verifyDeliveryV2: Live, Network, Media, Chat, Community, Games, Tools, Tips, VIP, News, Reviews, Deals, Trade and Search). The rotation overlap still signs v2 with both secrets. Tests assert there is no v1 header and verify v2. npm test 18/18.OpenVibers · 28 Sept 2026
f55f7eb -
/limits.json lists the per-actor rate limits as rate_limits (roadmap WS-R task 4), so Codes' limits page shows what is enforced: every named limit the routes declared, with its numbers per caller per minute and hour and what a caller gets past it. The limiter records each limit as a route declares it; with EVENTS_LIMITS=off the list is empty. test/pull-health.test.js checks the list. npm test 18/18.OpenVibers · 28 Sept 2026
1c26536 -
Per-actor rate limits at Events' capability routes (roadmap WS-R task 4): openvibe-sdk v0.12.0 is now a dependency, and server/actor-limits.js makes one limiter per app that counts each verified principal (svc:live, app:app_…) after its guard and before any work. Past a limit a route answers 429 problem+json rate_limited with Retry-After, logs one [limits] line and counts events_rate_limited_total{limit,window}.OpenVibers · 28 Sept 2026
7530c2f -
SSRF suite for app endpoints and a ratchet over outbound calls (roadmap WS-R task 5: SSRF). test/security-ssrf.test.js tries every internal spelling where an app subscription is made and again where each delivery is made, through the real guard with a stub DNS: loopback, RFC1918, CGNAT, 169.254.169.254, ::1, ::, ::ffff:127.0.0.1, ::ffff:7f00:1, fc00::/7, fe80::, NAT64 64:ff9b::7f00:1, 6to4 2002:7f00:1::, decimal, octal and hex IPv4, 0.0.0.0, trailing-dot and internal names, userinfo tricks, plain http, names resolving to any of those and mixed answers. Every one is refused at creation (422) and by the guard itself at delivery (permanent, nothing sent, no internal address ever approved for a connection); a name answering public first and internal next is accepted, then dead at once with nothing sent; redirects are never followed, for app and first-party endpoints alike; the first-party allow-list refuses its lookalikes. A ratchet lists every outbound call site in server/ (comments stripped) with where it goes; a new one fails until reviewed. No bug found: the guard held.OpenVibers · 26 Sept 2026
0fcd17a -
IDOR suite, and an app's subscriptions are scoped to its project and environment (roadmap WS-R task 5: IDOR; low). test/security-idor.test.js swaps ids between two apps, two projects, two environments and two services: reading, rotating, disabling and enabling another consumer's subscription gets 404; publishing into another project's namespace, as another app's source or actor, into a first-party namespace, or as another service is refused; apps and services without the operator capability (an app token carrying it included) read no deliveries and replay nothing; checkpoints of another project's pattern are refused. Every refusal leaves subscriptions, events, deliveries and checkpoints as they were; positive controls show each route works for its owner.OpenVibers · 26 Sept 2026
04a2857 -
Private-bypass suite, and an app token is never a realtime service viewer (roadmap WS-R task 5: private bypass; low). test/security-private.test.js publishes public, internal and per-person subject events and app events in two projects and both environments, each with a marker, and compares what every caller gets back: pull reads by every topic pattern and every event id (first-party readers see first-party production events and production app events only through app.*; an app its own project in its own environment plus public first-party events; people and anonymous nothing), the realtime stream replayed from the start (anonymous public only; a person also their own subject events by ticket, cookie or Bearer; services everything first-party; nobody an app event), DLQ views and replay (the operator's; replay never widens a subscription: by id or from the start only the subscription's own events go out), subscription listings, single reads and checkpoints (the caller's own).OpenVibers · 26 Sept 2026
2ad3f53 -
Security crawl for secrets (roadmap WS-R task 5: internal-secret leak). Events holds one kind of secret, each subscription's signing secret, and reads none from its environment (test/security-secrets.test.js asserts that: a new secret-looking variable fails until it gets a sentinel). With service and app subscriptions whose secrets were rotated (both sign during the overlap), every GET route Express knows after boot (test/security-crawl.js walks the router stack, so a new route is crawled without anyone listing it) is requested with seeded and nonsense ids and several query strings, the realtime stream read for a moment, as anonymous, two people, three services, a reader and three developer apps; every write route gets malformed JSON and empty bodies, every route forged, alg-none, expired and wrong-audience tokens. No answer may carry a subscription secret (also URL-encoded or base64), another caller's token or any part of Network's private key; the deliveries sent, the log and every table but subscriptions neither. test/security-world.js is the shared fixture for the security suites.OpenVibers · 26 Sept 2026
7efb758 -
Project usage rollups (roadmap WS-N task 4; Contracts v0.63.0 events.usage.recorded, common.usage-recorded@1): each developer project's use is counted per environment and UTC hour in the transaction that does the work (server/usage.js, table app_usage): events.app.publish in events (events stored in insertBatch; a repeated event_id is not counted), every refused publish request as an error with its problem code, status, trace id and the refused event id; events.app.subscribe in deliveries (webhook attempts to the project's subscriptions, recorded with the delivery row in recordAttempt), an attempt without a 2xx as events.delivery.http_<status>, .timeout or .failed with the event id and its trace. A minute after an hour closes, each rollup is stored once as an events.usage.recorded event (source events, subject the project, visibility internal, priority low) in the transaction that marks it sent, so Events is its own outbox; first-party subscribers (Network's project usage) get it like any event, apps never see it; a count landing in an hour already sent re-sends it as revision 2. EVENTS_USAGE=off counts nothing; EVENTS_USAGE_FLUSH_MS (300000). Pins: openvibe-contracts 0.61.0 -> 0.63.0. test/usage.test.jsOpenVibers · 26 Sept 2026
bb78877 -
Pins: openvibe-shared 1.20.0 -> 1.22.0 (realtime notification badge, off until a site turns it on; the unreachable-host browser check)OpenVibers · 26 Sept 2026
eb98f8c -
nginx: /realtime/stream is logged without its query string (log_format ov_events_noquery in conf.d), so the single-use ?ticket= never reaches the access log; installed on the hostOpenVibers · 26 Sept 2026
52e1615 -
Pins: openvibe-contracts -> 0.61.0 (network.notification.created@1, identity.realtime-ticket-claims@1, network.realtime-ticket-result@1)OpenVibers · 26 Sept 2026
3252f62 -
Realtime tickets (roadmap WS-E task 3, WS-F task 1; ADR-005 amendment 2, Contracts 0.61.0 identity.realtime-ticket-claims@1): /realtime/stream?ticket= opens a stream as the signed-in person from any OpenVibe site without a third-party cookie. The ticket is Network's two-minute RS256 JWT (iss <issuer>/realtime, sub usr_, aud openvibe.events only, typ and purpose realtime, lifetime at most 300 s, jti rtk_); each is accepted once (ticket.used), never as Bearer or cookie, never logged; ticket.invalid / ticket.expired otherwise. A user JWT carrying typ or purpose is no session here. test/realtime-tickets.test.js: a ticket for Alice never receives Bob's network.notification.created on any pattern (live or replay), user:<id> is refused as a pattern, expired/wrong purpose/typ/audience/issuer/key/lifetime/reused/session-JWT tickets refused, resume from last_event_id with a fresh ticket, retention gap reported firstOpenVibers · 26 Sept 2026
aa34acb -
Export tokens pinned (roadmap WS-N task 9): OpenVibe.Codes' project archive pulls a project's app events with Network's read-only export token (sub app:app_<project ULID>, events.app.read, env, purpose export). Events takes it unchanged; test/export-tokens.test.js pins that it pulls the project's events of the token's environment page by page, and cannot read another project, publish, subscribe or reach operator routesOpenVibers · 26 Sept 2026
272da87 -
Pins: openvibe-shared 1.18.0 -> 1.20.0 (the update matrix and release manifest 1.2.0: client generations, the shell)OpenVibers · 26 Sept 2026
a38de79 -
Pins: openvibe-shared 1.17.1 -> 1.18.0 (update telemetry: prompted count, sessions by generation)OpenVibers · 26 Sept 2026
390f1cd -
Limits page source (roadmap WS-N task 7): GET /limits.json lists the developer limits enforced here per project and environment (publish rate, bytes kept, retention, webhook subscriptions, payload and batch size, realtime topics), read from the running config, with the problem each one answers past it. A quota config turns off with 0 is null. Public, CORS *, proxied by the vhost; openvibe.codes/docs/limits renders itOpenVibers · 26 Sept 2026
5889c2c -
Pins: openvibe-shared 1.16.1 -> 1.17.1 (release notifications)OpenVibers · 26 Sept 2026
5f1eafb -
Pins: openvibe-shared 1.16.0 -> 1.16.1 (the OV mark stops animating when idle, hidden or off-screen)OpenVibers · 26 Sept 2026
dfa5e12 -
nginx: the commented template for exposing /api/ sets the client-IP headers from $remote_addr (X-Real-IP, X-Forwarded-For, CF-Connecting-IP), like every active location, instead of $proxy_add_x_forwarded_for, which passes a client-sent X-Forwarded-For through if someone uncomments it (browser-check follow-up, WS-Q task 3; the active locations already set all three). Comment onlyOpenVibers · 26 Sept 2026
e6dd3c1 -
Pins: openvibe-shared 1.13.0 -> 1.16.0OpenVibers · 26 Sept 2026
39eba17 -
Pins: openvibe-contracts 0.44.0 → 0.49.0, openvibe-shared 1.12.0 → 1.13.0OpenVibers · 25 Sept 2026
e2cb9ea -
Pins: openvibe-contracts 0.42.0 → 0.44.0 (Contracts 0.43.0 and 0.44.0 were released after the previous pin commit, leaving 0.42.0 two minors behind the pin-drift limit)OpenVibers · 25 Sept 2026
4a83adc -
Pins: openvibe-contracts 0.33.0 → 0.42.0, openvibe-shared 1.6.0 → 1.12.0; CI runs the pin-drift check (shared test and security workflows at 423fe51)OpenVibers · 25 Sept 2026
7074fb6 -
CI calls the shared test workflow (Track Q): OpenVibe.Shared test.yml@e8b0caf (install, node --check, npm test, openvibe-contracts-check; ffmpeg where the tests need it) instead of a copy of those stepsOpenVibers · 24 Sept 2026
eb68bb7 -
App-endpoint guard on openvibe-shared 1.6.0: the public-address rule and internal-name list come from openvibe-shared/egress (shared with Live and Tools; adds *.home.arpa); endpoint syntax rules and the connect-time guarded POST stay hereOpenVibers · 24 Sept 2026
3879798 -
rotate-subscription-secret: --consumer rotates every first-party subscription of a service to one new secret (they share one env variable)OpenVibers · 24 Sept 2026
9f51514