openvibers/openvibe.tools Commits
README and STATUS.json are current (roadmap WS-U task 3): the README gains Purpose (the opening overview), Owns, Does not own, Depends on (the per-app pins: contracts v0.63.0, sdk v0.12.0, shared v1.23.0), Capabilities (the six tools.* capabilities and the grants Tools uses at Media, Events and Search) and Security (SECURITY.md, the guard, egress, auth, secrets by name) sections; Deploy opens with sudo ovhost deploy tools and the rollback. Stale facts corrected: pages load the shared files from their own app's pinned copy (since 390d3df), not openvibe.network, and the SDK test uses the pinned SDK, not v0.6.0. STATUS.json is new, in the shape of Search's, updated 2026-09-28.
Changes
@@@ -1,5 +1,7 @@# OpenVibe.Tools++## Purpose++The tools suite of the OpenVibe network — `openvibe.tools` plus dozens oftool subdomains under `*.openvibe.tools`.@@@ -9,6 +11,42 @@ This repo contains no identity provider: the gateway is an OAuth2 **client**`.openvibe.tools`; every satellite reads that cookie and verifies the JWToffline against the Network's public key (JWKS).++## Owns++++- the tool registry (families, tools, descriptors `tools.tool@1`, canonical, short and alias hosts),++ the catalog and every tool page on `openvibe.tools` and `*.openvibe.tools`++- the run API and the jobs runtime (img, audio, docs jobs with their files and SSE progress), the++ guard (callers, quotas, sniffing, egress throttles, abuse log) and each app's `data/guard.db`++- the `tools.*` events, Tools' Search documents and the `tools.usage` user module++++## Does not own++++- identity and sign-in (OpenVibe.Network), pastes (OpenVibe.Community: `pastes.openvibe.tools` hands over),++ result storage (OpenVibe.Media keeps job results), custom-domain records (Network's domains admin)++++## Depends on++++- OpenVibe.Network (SSO as OAuth client `tools`, JWKS, client-credentials tokens, the domains registry),++ OpenVibe.Media (job results), OpenVibe.Events (job and usage events, revocation cutoffs),++ OpenVibe.Search (tool documents), OpenVibe.Community (the paste hand-over)++- host programs some tools need (ffmpeg, yt-dlp, qpdf, poppler, libheif; [Host packages](#host-packages-some-tools-need))++- in each app: `openvibe-contracts` v0.63.0, `openvibe-sdk` v0.12.0 and `openvibe-shared` v1.23.0, pinned++ by release tarball, and `apps/_shared` (openvibe-tools-shared) by relative path++++## Capabilities++++Implemented here (the service manifest's `capabilities`, audience `openvibe.tools`): `tools.tool.read`++(the public registry API), `tools.tool.run` (the run API), `tools.job.create`, `tools.job.read` and++`tools.job.cancel` (jobs), and `tools.net.probe` (network probes).++++Called elsewhere, as the service principal `tools` (the OAuth client `tools`):++++| Service | Grant | Why |++|---|---|---|++| OpenVibe.Media | `media.object.upload`, `media.object.read` | job results |++| OpenVibe.Events | `events.event.publish`, `events.subscription.manage` | job and usage events; the `network.user.token_valid_after` subscription |++| OpenVibe.Search | `search.document.write` | tool documents for the network index |++## Layout```@@@ -434,7 +472,7 @@ the run API on the gateway, img and docs (with a stand-in Network for tokens, `aevery answer against `tools.run@1`, the refusal codes, probes, quotas, idempotency, job tools and referencesacross satellites, the Origin check and the deprecation headers; `jobs-facade.test.js` routes jobs through thegateway (by type, by id after a restart, events, files, retry, cancel); `sdk-client.test.js` drives--openvibe-sdk v0.6.0's `createToolsClient` against the real gateway (it requires a checkout of OpenVibe.SDK next to++the pinned openvibe-sdk's `createToolsClient` against the real gateway (it requires a checkout of OpenVibe.SDK next tothis repo, or `OV_SDK_DIR`, and says it skipped without one); `pool.test.js` (shared and docs) hold the workerpool to its limits. The audio tests need`ffmpeg` and skip without it. The docs and img tests always check the 503 path with qpdf, poppler and libheif@@@ -550,11 +588,29 @@ The full OAuth round-trip needs OpenVibe.Network running on port 4000- `GET /auth/me`, `POST /auth/refresh`, `GET /auth/logout`.- Satellites never talk OAuth — they read `ov_token` and verify offlinevia the Network JWKS (`GET /api/.well-known/jwks`).--- Browser pages load shared JS absolutely from-- `https://openvibe.network/shared/` (theme-loader, navbar, …).++- Browser pages load the shared files (theme-loader, navbar, …) from their++ own app's pinned copy at `/shared/` (`apps/_shared/release.js`,++ `openvibe-shared/serve`), not from openvibe.network.++++## Security++++Reporting a vulnerability: [SECURITY.md](SECURITY.md). The rules are in [Guard](#guard-anti-abuse-apps_sharedguard)++and [Auth model](#auth-model); in short: every caller is identified (principal, user with audience++`openvibe.tools`, session or address) and held to per-tier quotas and per-actor limits; uploads are++sniffed against the descriptor; every tool that reaches a visitor-chosen host goes through the SSRF guard++(`apps/_shared/egress.js`: public addresses only, checked after DNS, redirect hops re-checked); `trust proxy`++is one loopback hop; sign-in `next` accepts only relative paths, `*.openvibe.tools` and `openvibe.network`.++Secrets (`OV_OAUTH_CLIENT_SECRET`, `TOOLS_EVENTS_SECRET`, `NET_IPINFO_TOKEN`, `RIDB_API_KEY`, `NPS_API_KEY`,++`OPEN_CHARGE_MAP_KEY`, `YT_COOKIES_FILE`, the fallback `INTERNAL_API_KEY`) live in `/etc/openvibe/tools.env`++(0600), by name only.## Deploy++Production deploys with `sudo ovhost deploy tools` (`deploy/scripts/deploy.sh` is the wrapper; strategy++`multi-app`, described under [Registry, hosts and domains](#registry-hosts-and-domains)). Rollback: automatic++when the gateway's `/api/ready` or `/release.json` does not come up with every unit active; afterwards++`sudo ovhost rollback tools --to <sha>`. Nothing blocks a rollback: the schema code only adds.++- Production path: `/opt/openvibe.tools` (apps under `apps/<name>`)- Env file: `/etc/openvibe/tools.env` (0600) — shared by all units; per-app`PORT` is set in each systemd unit, so tools.env must NOT define PORT.nnew file mode 100644@@@ -0,0 +1,36 @@++{++ "repository": "OpenVibers/OpenVibe.Tools",++ "stage": "stable",++ "code": true,++ "plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",++ "runtime": "node 22, express, better-sqlite3; eight apps (gateway, maps, food, img, yt, audio, text, docs)",++ "port": 4001,++ "ports": {++ "gateway": 4001,++ "maps": 4010,++ "food": 4011,++ "img": 4012,++ "yt": 4013,++ "audio": 4014,++ "text": 4015,++ "docs": 4016++ },++ "domain": "openvibe.tools and *.openvibe.tools",++ "contracts": "openvibe-contracts v0.63.0 (each app's package.json; the root package.json pins none)",++ "capabilities": ["tools.job.create", "tools.job.read", "tools.job.cancel", "tools.tool.read", "tools.tool.run", "tools.net.probe"],++ "capabilitiesRegistered": true,++ "deployed": true,++ "deployment": "Public at https://openvibe.tools: deployed with `sudo ovhost deploy tools` (OpenVibe.Host strategy multi-app since the 2026-09-27 cutover; deploy/scripts/deploy.sh is the wrapper), /opt/openvibe.tools, units openvibe-tools (gateway, 127.0.0.1:4001) and openvibe-tools-<app> per satellite, env /etc/openvibe/tools.env.",++ "features": [++ "tool registry with descriptors, canonical hosts, aliases and owner-attached custom domains",++ "server-rendered catalog and tool pages with full SEO",++ "public registry API (tools.tool.read) and run API (tools.tool.run)",++ "jobs runtime for img, audio and docs with SSE progress and Media results",++ "net and dev tools on the gateway; maps, food, img, yt, audio, text and docs satellites",++ "guard: callers, tiered quotas, upload sniffing, SSRF-safe egress, abuse log",++ "tools.* events and Search documents",++ "analytics within ADR-021",++ "per-actor limits (openvibe-sdk/limits)"++ ],++ "updated": "2026-09-28"++}
@@ -1,5 +1,7 @@
@@ -1,5 +1,7 @@
# OpenVibe.Tools
# OpenVibe.Tools
+## Purpose
+
The tools suite of the OpenVibe network — `openvibe.tools` plus dozens of
The tools suite of the OpenVibe network — `openvibe.tools` plus dozens of
tool subdomains under `*.openvibe.tools`.
tool subdomains under `*.openvibe.tools`.
@@ -9,6 +11,42 @@ This repo contains no identity provider: the gateway is an OAuth2 **client**
@@ -9,6 +11,42 @@ This repo contains no identity provider: the gateway is an OAuth2 **client**
`.openvibe.tools`; every satellite reads that cookie and verifies the JWT
`.openvibe.tools`; every satellite reads that cookie and verifies the JWT
offline against the Network's public key (JWKS).
offline against the Network's public key (JWKS).
+## Owns
+
+- the tool registry (families, tools, descriptors `tools.tool@1`, canonical, short and alias hosts),
+ the catalog and every tool page on `openvibe.tools` and `*.openvibe.tools`
+- the run API and the jobs runtime (img, audio, docs jobs with their files and SSE progress), the
+ guard (callers, quotas, sniffing, egress throttles, abuse log) and each app's `data/guard.db`
+- the `tools.*` events, Tools' Search documents and the `tools.usage` user module
+
+## Does not own
+
+- identity and sign-in (OpenVibe.Network), pastes (OpenVibe.Community: `pastes.openvibe.tools` hands over),
+ result storage (OpenVibe.Media keeps job results), custom-domain records (Network's domains admin)
+
+## Depends on
+
+- OpenVibe.Network (SSO as OAuth client `tools`, JWKS, client-credentials tokens, the domains registry),
+ OpenVibe.Media (job results), OpenVibe.Events (job and usage events, revocation cutoffs),
+ OpenVibe.Search (tool documents), OpenVibe.Community (the paste hand-over)
+- host programs some tools need (ffmpeg, yt-dlp, qpdf, poppler, libheif; [Host packages](#host-packages-some-tools-need))
+- in each app: `openvibe-contracts` v0.63.0, `openvibe-sdk` v0.12.0 and `openvibe-shared` v1.23.0, pinned
+ by release tarball, and `apps/_shared` (openvibe-tools-shared) by relative path
+
+## Capabilities
+
+Implemented here (the service manifest's `capabilities`, audience `openvibe.tools`): `tools.tool.read`
+(the public registry API), `tools.tool.run` (the run API), `tools.job.create`, `tools.job.read` and
+`tools.job.cancel` (jobs), and `tools.net.probe` (network probes).
+
+Called elsewhere, as the service principal `tools` (the OAuth client `tools`):
+
+| Service | Grant | Why |
+|---|---|---|
+| OpenVibe.Media | `media.object.upload`, `media.object.read` | job results |
+| OpenVibe.Events | `events.event.publish`, `events.subscription.manage` | job and usage events; the `network.user.token_valid_after` subscription |
+| OpenVibe.Search | `search.document.write` | tool documents for the network index |
+
## Layout
## Layout
```
```
@@ -434,7 +472,7 @@ the run API on the gateway, img and docs (with a stand-in Network for tokens, `a
@@ -434,7 +472,7 @@ the run API on the gateway, img and docs (with a stand-in Network for tokens, `a
every answer against `tools.run@1`, the refusal codes, probes, quotas, idempotency, job tools and references
every answer against `tools.run@1`, the refusal codes, probes, quotas, idempotency, job tools and references
across satellites, the Origin check and the deprecation headers; `jobs-facade.test.js` routes jobs through the
across satellites, the Origin check and the deprecation headers; `jobs-facade.test.js` routes jobs through the
gateway (by type, by id after a restart, events, files, retry, cancel); `sdk-client.test.js` drives
gateway (by type, by id after a restart, events, files, retry, cancel); `sdk-client.test.js` drives
-openvibe-sdk v0.6.0's `createToolsClient` against the real gateway (it requires a checkout of OpenVibe.SDK next to
+the pinned openvibe-sdk's `createToolsClient` against the real gateway (it requires a checkout of OpenVibe.SDK next to
this repo, or `OV_SDK_DIR`, and says it skipped without one); `pool.test.js` (shared and docs) hold the worker
this repo, or `OV_SDK_DIR`, and says it skipped without one); `pool.test.js` (shared and docs) hold the worker
pool to its limits. The audio tests need
pool to its limits. The audio tests need
`ffmpeg` and skip without it. The docs and img tests always check the 503 path with qpdf, poppler and libheif
`ffmpeg` and skip without it. The docs and img tests always check the 503 path with qpdf, poppler and libheif
@@ -550,11 +588,29 @@ The full OAuth round-trip needs OpenVibe.Network running on port 4000
@@ -550,11 +588,29 @@ The full OAuth round-trip needs OpenVibe.Network running on port 4000
- `GET /auth/me`, `POST /auth/refresh`, `GET /auth/logout`.
- `GET /auth/me`, `POST /auth/refresh`, `GET /auth/logout`.
- Satellites never talk OAuth — they read `ov_token` and verify offline
- Satellites never talk OAuth — they read `ov_token` and verify offline
via the Network JWKS (`GET /api/.well-known/jwks`).
via the Network JWKS (`GET /api/.well-known/jwks`).
-- Browser pages load shared JS absolutely from
- `https://openvibe.network/shared/` (theme-loader, navbar, …).
+- Browser pages load the shared files (theme-loader, navbar, …) from their
+ own app's pinned copy at `/shared/` (`apps/_shared/release.js`,
+ `openvibe-shared/serve`), not from openvibe.network.
+
+## Security
+
+Reporting a vulnerability: [SECURITY.md](SECURITY.md). The rules are in [Guard](#guard-anti-abuse-apps_sharedguard)
+and [Auth model](#auth-model); in short: every caller is identified (principal, user with audience
+`openvibe.tools`, session or address) and held to per-tier quotas and per-actor limits; uploads are
+sniffed against the descriptor; every tool that reaches a visitor-chosen host goes through the SSRF guard
+(`apps/_shared/egress.js`: public addresses only, checked after DNS, redirect hops re-checked); `trust proxy`
+is one loopback hop; sign-in `next` accepts only relative paths, `*.openvibe.tools` and `openvibe.network`.
+Secrets (`OV_OAUTH_CLIENT_SECRET`, `TOOLS_EVENTS_SECRET`, `NET_IPINFO_TOKEN`, `RIDB_API_KEY`, `NPS_API_KEY`,
+`OPEN_CHARGE_MAP_KEY`, `YT_COOKIES_FILE`, the fallback `INTERNAL_API_KEY`) live in `/etc/openvibe/tools.env`
+(0600), by name only.
## Deploy
## Deploy
+Production deploys with `sudo ovhost deploy tools` (`deploy/scripts/deploy.sh` is the wrapper; strategy
+`multi-app`, described under [Registry, hosts and domains](#registry-hosts-and-domains)). Rollback: automatic
+when the gateway's `/api/ready` or `/release.json` does not come up with every unit active; afterwards
+`sudo ovhost rollback tools --to <sha>`. Nothing blocks a rollback: the schema code only adds.
+
- Production path: `/opt/openvibe.tools` (apps under `apps/<name>`)
- Production path: `/opt/openvibe.tools` (apps under `apps/<name>`)
- Env file: `/etc/openvibe/tools.env` (0600) — shared by all units; per-app
- Env file: `/etc/openvibe/tools.env` (0600) — shared by all units; per-app
`PORT` is set in each systemd unit, so tools.env must NOT define PORT.
`PORT` is set in each systemd unit, so tools.env must NOT define PORT.
new file mode 100644
new file mode 100644
@@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
+{
+ "repository": "OpenVibers/OpenVibe.Tools",
+ "stage": "stable",
+ "code": true,
+ "plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
+ "runtime": "node 22, express, better-sqlite3; eight apps (gateway, maps, food, img, yt, audio, text, docs)",
+ "port": 4001,
+ "ports": {
+ "gateway": 4001,
+ "maps": 4010,
+ "food": 4011,
+ "img": 4012,
+ "yt": 4013,
+ "audio": 4014,
+ "text": 4015,
+ "docs": 4016
+ },
+ "domain": "openvibe.tools and *.openvibe.tools",
+ "contracts": "openvibe-contracts v0.63.0 (each app's package.json; the root package.json pins none)",
+ "capabilities": ["tools.job.create", "tools.job.read", "tools.job.cancel", "tools.tool.read", "tools.tool.run", "tools.net.probe"],
+ "capabilitiesRegistered": true,
+ "deployed": true,
+ "deployment": "Public at https://openvibe.tools: deployed with `sudo ovhost deploy tools` (OpenVibe.Host strategy multi-app since the 2026-09-27 cutover; deploy/scripts/deploy.sh is the wrapper), /opt/openvibe.tools, units openvibe-tools (gateway, 127.0.0.1:4001) and openvibe-tools-<app> per satellite, env /etc/openvibe/tools.env.",
+ "features": [
+ "tool registry with descriptors, canonical hosts, aliases and owner-attached custom domains",
+ "server-rendered catalog and tool pages with full SEO",
+ "public registry API (tools.tool.read) and run API (tools.tool.run)",
+ "jobs runtime for img, audio and docs with SSE progress and Media results",
+ "net and dev tools on the gateway; maps, food, img, yt, audio, text and docs satellites",
+ "guard: callers, tiered quotas, upload sniffing, SSRF-safe egress, abuse log",
+ "tools.* events and Search documents",
+ "analytics within ADR-021",
+ "per-actor limits (openvibe-sdk/limits)"
+ ],
+ "updated": "2026-09-28"
+}