openvibers/openvibe.network Commits
Tools grants: live, chat and community hold tools.tool.run and tools.job.read on openvibe.tools, so their Tools run API calls (kiosk page titles, audio conversion, save-as-paste) run on the service tier, never network probes
Changes
@@@ -155,6 +155,9 @@ const DEFAULT_GRANTS = [// or ledger.admin: approving payouts is a separately controlled capability (ADR-012 rule 10)....['billing.intent.create', 'billing.transfer.create', 'billing.balance.read', 'billing.cashout.request','billing.subscription.manage', 'billing.entitlement.check'].map(c => ['live', c, 'openvibe.billing', []]),++ // Tools platform S9: products call the Tools run API (the kiosk's page titles, Chat's audio conversion,++ // Community's save-as-paste) with their own token, on the service tier instead of the anonymous one.++ ...['live', 'chat', 'community'].flatMap(c => ['tools.tool.run', 'tools.job.read'].map(cap => [c, cap, 'openvibe.tools', []])),];// Grants withdrawn by decision; applied at every boot so an old default can't come back.@@@ -137,6 +137,8 @@ const server = http.createServer(app);assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);++ const tl = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.tools' });++ assert.deepStrictEqual(tl.body.scope.split(' '), ['tools.job.read', 'tools.tool.run'], 'Live runs Tools on the service tier, never probes');// Go-live fan-out accepts Live's token (network.notifications.push); a narrower token is refused.r = await post('/internal/events/stream-live', {}, { authorization: `Bearer ${full}` });
@@ -155,6 +155,9 @@ const DEFAULT_GRANTS = [
@@ -155,6 +155,9 @@ const DEFAULT_GRANTS = [
// or ledger.admin: approving payouts is a separately controlled capability (ADR-012 rule 10).
// or ledger.admin: approving payouts is a separately controlled capability (ADR-012 rule 10).
...['billing.intent.create', 'billing.transfer.create', 'billing.balance.read', 'billing.cashout.request',
...['billing.intent.create', 'billing.transfer.create', 'billing.balance.read', 'billing.cashout.request',
'billing.subscription.manage', 'billing.entitlement.check'].map(c => ['live', c, 'openvibe.billing', []]),
'billing.subscription.manage', 'billing.entitlement.check'].map(c => ['live', c, 'openvibe.billing', []]),
+ // Tools platform S9: products call the Tools run API (the kiosk's page titles, Chat's audio conversion,
+ // Community's save-as-paste) with their own token, on the service tier instead of the anonymous one.
+ ...['live', 'chat', 'community'].flatMap(c => ['tools.tool.run', 'tools.job.read'].map(cap => [c, cap, 'openvibe.tools', []])),
];
];
// Grants withdrawn by decision; applied at every boot so an old default can't come back.
// Grants withdrawn by decision; applied at every boot so an old default can't come back.
@@ -137,6 +137,8 @@ const server = http.createServer(app);
@@ -137,6 +137,8 @@ const server = http.createServer(app);
assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');
assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');
const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });
const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });
assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);
assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);
+ const tl = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.tools' });
+ assert.deepStrictEqual(tl.body.scope.split(' '), ['tools.job.read', 'tools.tool.run'], 'Live runs Tools on the service tier, never probes');
// Go-live fan-out accepts Live's token (network.notifications.push); a narrower token is refused.
// Go-live fan-out accepts Live's token (network.notifications.push); a narrower token is refused.
r = await post('/internal/events/stream-live', {}, { authorization: `Bearer ${full}` });
r = await post('/internal/events/stream-live', {}, { authorization: `Bearer ${full}` });