openvibers/openvibe.live Commits

Require live.agent_sandbox.register from the released Contracts registry (#658)

OP OpenVibers committed 6 days ago · 5c0f48e1ba · 4 files, +21 −18

Pin openvibe-contracts v0.314.0, which names live.agent_sandbox.register, and check
the service token against that capability with capabilities.check. The temporary
acceptance of the design's hyphen spelling goes with the fallback: a token that
carries live.agent-sandbox.register is no longer a registration.

The S6 test states the release Live is pinned to knows the capability, its owner and
its route, beside the existing refusals.

Changes

ddiff --git a/package-lock.json b/package-lock.json
iindex edeeb3c0..cd616d33 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -23,7 +23,7 @@
"multer": "^1.4.5-lts.1",
"node-media-server": "^2.7.1",
"onnxruntime-node": "^1.20.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.305.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.314.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.93.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.124.0",
"pg": "^8.23.1",
@@@ -2840,9 +2840,9 @@
}
},
"node_modules/openvibe-contracts": {
-- "version": "0.305.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.305.0",
-- "integrity": "sha512-jTU1zlnTmHlydwL3/c5HVdUiPpd8r2KucVdHYUYX5MZgJoqy4M7Hg2jy6UKbJQ6s665uIZyTvswbmJjB2uwc5Q==",
++ "version": "0.314.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.314.0",
++ "integrity": "sha512-sq5idLBEw+fWc4J63QvmZocf6dxq91qrtsUFzU362uKJ2hpXFQFtos2gGx1oeAyqmKL/5YfEikc/uKNY0v/x5w==",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex aed358cd..e98c1d96 100644
---- a/package.json
++++ b/package.json
@@@ -42,7 +42,7 @@
"multer": "^1.4.5-lts.1",
"node-media-server": "^2.7.1",
"onnxruntime-node": "^1.20.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.305.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.314.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.93.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.124.0",
"pg": "^8.23.1",
ddiff --git a/server/agent-streams/auth.js b/server/agent-streams/auth.js
iindex b2529def..03f266dd 100644
---- a/server/agent-streams/auth.js
++++ b/server/agent-streams/auth.js
@@@ -24,11 +24,9 @@ const AUDIENCE = 'openvibe.live';
// before the registry entry is pinned still works.
const CAPABILITIES = ['live.agent_stream.publish', 'live.agent-stream.publish'];
const CAPABILITY = CAPABILITIES[0];
--// The sandbox worker (S6): the capability that lets OpenVibe's sandbox worker register itself. The
--// registry's id carries no hyphen; the design's spelling is accepted too, so a token minted before the
--// registry entry is pinned still works.
--const SANDBOX_CAPABILITIES = ['live.agent_sandbox.register', 'live.agent-sandbox.register'];
--const SANDBOX_CAPABILITY = SANDBOX_CAPABILITIES[0];
++// The sandbox worker (S6): the capability that lets OpenVibe's sandbox worker register itself, as the
++// pinned Contracts release names it (a capability id carries no hyphen).
++const SANDBOX_CAPABILITY = 'live.agent_sandbox.register';
const FIRST_PARTY_SUB = /^(svc|node):/;
/** The local account linked to a Network subject, or null. */
@@@ -109,15 +107,11 @@ async function publisher(req, res, next) {
}
}
--/** The capability on a service token, with the pinned registry's check when it knows the id. */
++/** The sandbox registration capability on a service token, checked against the pinned registry. */
function holdsSandboxCapability(claims) {
const c = claims || {};
-- if (!Array.isArray(c.cap)) return false;
-- return SANDBOX_CAPABILITIES.some((capability) => {
-- if (!c.cap.includes(capability)) return false;
-- if (contracts.capabilities.get(capability)) return contracts.capabilities.check(c, capability).allowed;
-- return contracts.capabilities.grants(c.cap, capability);
-- });
++ if (!Array.isArray(c.cap) || !c.cap.includes(SANDBOX_CAPABILITY)) return false;
++ return contracts.capabilities.check(c, SANDBOX_CAPABILITY).allowed;
}
/**
@@@ -185,4 +179,4 @@ async function userFromToken(token) {
return decoded ? await resolveNetworkUser(decoded) : null;
}
--module.exports = { publisher, viewer, viewerSubject, userForSubject, userFromToken, holdsCapability, holdsSandboxCapability, sandboxRegistrar, AUDIENCE, CAPABILITY, CAPABILITIES, SANDBOX_CAPABILITY, SANDBOX_CAPABILITIES };
++module.exports = { publisher, viewer, viewerSubject, userForSubject, userFromToken, holdsCapability, holdsSandboxCapability, sandboxRegistrar, AUDIENCE, CAPABILITY, CAPABILITIES, SANDBOX_CAPABILITY };
ddiff --git a/test/agent-streams-s6.test.js b/test/agent-streams-s6.test.js
iindex d2f1b225..07f4c00b 100644
---- a/test/agent-streams-s6.test.js
++++ b/test/agent-streams-s6.test.js
@@@ -42,6 +42,12 @@ async function check(name, fn) {
VALUES (1, 'ann', 'ann', 'ann@x', 'x', 'streamer', 0) ON CONFLICT (id) DO NOTHING`).run();
await raw.prepare("INSERT INTO linked_accounts (user_id, service, service_user_id, subject_id) VALUES (1, 'network', '101', ?) ON CONFLICT DO NOTHING").run(SID.ann);
++ // The capability is the one the pinned Contracts release names, and the old hyphen spelling is not a grant.
++ const contracts = require('openvibe-contracts');
++ const cap = contracts.capabilities.get('live.agent_sandbox.register');
++ assert.ok(cap, 'the pinned contracts know live.agent_sandbox.register');
++ assert.strictEqual(cap.owner, 'live');
++ assert.ok(cap.implementedBy.includes('POST /api/streams/agent/:id/plays/worker'), 'the capability names the registration route');
// The Network is not here: a service token is verified by this stand-in. The worker's token holds the
// sandbox capability; the other one does not.
const sdkAuth = require('openvibe-sdk/auth');
@@@ -51,6 +57,9 @@ async function check(name, fn) {
if (token === 'tok-person') return { ok: true, claims: { sub: SID.ann, cap: ['live.agent_sandbox.register'] } };
return { ok: false, code: 'token.invalid' };
};
++ const auth = require('../server/agent-streams/auth');
++ assert.strictEqual(auth.holdsSandboxCapability({ cap: ['live.agent_sandbox.register'] }), true);
++ assert.strictEqual(auth.holdsSandboxCapability({ cap: ['live.agent-sandbox.register'] }), false, 'the design spelling carries no grant');
const config = require('../server/config');
config.baseUrl = 'https://openvibe.live';