openvibers/openvibe.network Commits
principal_usage: record the auth method the request actually used (a refused X-Internal-Key was logged as an unknown service token)
Changes
@@@ -106,8 +106,9 @@ function recordDecision(db) {const up = db.prepare(`INSERT INTO principal_usage (principal, route, capability, auth, allowed, code, count) VALUES (?, ?, ?, ?, ?, ?, 1)ON CONFLICT(principal, route, auth, allowed, code) DO UPDATE SET count = count + 1, last_at = CURRENT_TIMESTAMP`);return ({ req, capability, principal, allowed, code }) => {-- const who = principal ? (principal.legacy ? 'legacy-key' : principal.sub) : 'unknown';-- const auth = principal && principal.legacy ? 'internal-key' : 'service-token';++ const bearer = String(req.headers.authorization || '').startsWith('Bearer ');++ const auth = bearer ? 'service-token' : req.internalKeyOk ? 'internal-key' : 'none';++ const who = principal ? (principal.legacy ? 'legacy-key' : principal.sub) : (auth === 'internal-key' ? 'legacy-key' : 'unknown');try { up.run(who, `${req.method} ${req.baseUrl || ''}${req.route ? req.route.path : req.path}`, capability, auth, allowed ? 1 : 0, code || ''); } catch { /* best effort */ }};}@@@ -78,6 +78,7 @@ const server = http.createServer(app);assert.strictEqual(r.status, 200); assert.strictEqual(r.body.data.voice, 'en-2');r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { 'x-internal-key': 'legacy-key' }, body: { data: { followers: 1 } } });assert.strictEqual(r.status, 403, 'module routes never accept the shared key');++ assert.ok(db.prepare("SELECT 1 FROM principal_usage WHERE principal = 'legacy-key' AND auth = 'internal-key' AND allowed = 0 AND route LIKE 'PUT /internal/modules%'").get(), 'a refused key is audited as the key');r = await call('PUT', `/internal/modules/live.profile/usr_01JAB2C3D4E5F6G7H8J9K0ZZZZ`, { headers: { authorization: `Bearer ${live}` }, body: { data: { followers: 1 } } });assert.strictEqual(r.status, 404, 'unknown subject');r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { authorization: `Bearer ${live}`, 'if-match': '0' }, body: { data: { followers: 43 } } });
@@ -106,8 +106,9 @@ function recordDecision(db) {
@@ -106,8 +106,9 @@ function recordDecision(db) {
const up = db.prepare(`INSERT INTO principal_usage (principal, route, capability, auth, allowed, code, count) VALUES (?, ?, ?, ?, ?, ?, 1)
const up = db.prepare(`INSERT INTO principal_usage (principal, route, capability, auth, allowed, code, count) VALUES (?, ?, ?, ?, ?, ?, 1)
ON CONFLICT(principal, route, auth, allowed, code) DO UPDATE SET count = count + 1, last_at = CURRENT_TIMESTAMP`);
ON CONFLICT(principal, route, auth, allowed, code) DO UPDATE SET count = count + 1, last_at = CURRENT_TIMESTAMP`);
return ({ req, capability, principal, allowed, code }) => {
return ({ req, capability, principal, allowed, code }) => {
- const who = principal ? (principal.legacy ? 'legacy-key' : principal.sub) : 'unknown';
- const auth = principal && principal.legacy ? 'internal-key' : 'service-token';
+ const bearer = String(req.headers.authorization || '').startsWith('Bearer ');
+ const auth = bearer ? 'service-token' : req.internalKeyOk ? 'internal-key' : 'none';
+ const who = principal ? (principal.legacy ? 'legacy-key' : principal.sub) : (auth === 'internal-key' ? 'legacy-key' : 'unknown');
try { up.run(who, `${req.method} ${req.baseUrl || ''}${req.route ? req.route.path : req.path}`, capability, auth, allowed ? 1 : 0, code || ''); } catch { /* best effort */ }
try { up.run(who, `${req.method} ${req.baseUrl || ''}${req.route ? req.route.path : req.path}`, capability, auth, allowed ? 1 : 0, code || ''); } catch { /* best effort */ }
};
};
}
}
@@ -78,6 +78,7 @@ const server = http.createServer(app);
@@ -78,6 +78,7 @@ const server = http.createServer(app);
assert.strictEqual(r.status, 200); assert.strictEqual(r.body.data.voice, 'en-2');
assert.strictEqual(r.status, 200); assert.strictEqual(r.body.data.voice, 'en-2');
r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { 'x-internal-key': 'legacy-key' }, body: { data: { followers: 1 } } });
r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { 'x-internal-key': 'legacy-key' }, body: { data: { followers: 1 } } });
assert.strictEqual(r.status, 403, 'module routes never accept the shared key');
assert.strictEqual(r.status, 403, 'module routes never accept the shared key');
+ assert.ok(db.prepare("SELECT 1 FROM principal_usage WHERE principal = 'legacy-key' AND auth = 'internal-key' AND allowed = 0 AND route LIKE 'PUT /internal/modules%'").get(), 'a refused key is audited as the key');
r = await call('PUT', `/internal/modules/live.profile/usr_01JAB2C3D4E5F6G7H8J9K0ZZZZ`, { headers: { authorization: `Bearer ${live}` }, body: { data: { followers: 1 } } });
r = await call('PUT', `/internal/modules/live.profile/usr_01JAB2C3D4E5F6G7H8J9K0ZZZZ`, { headers: { authorization: `Bearer ${live}` }, body: { data: { followers: 1 } } });
assert.strictEqual(r.status, 404, 'unknown subject');
assert.strictEqual(r.status, 404, 'unknown subject');
r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { authorization: `Bearer ${live}`, 'if-match': '0' }, body: { data: { followers: 43 } } });
r = await call('PUT', `/internal/modules/live.profile/${ANN}`, { headers: { authorization: `Bearer ${live}`, 'if-match': '0' }, body: { data: { followers: 43 } } });