Restrict the AI tab to HOST1 — the only node with the GPU, Ollama and the index

This commit is contained in:
Gmer4Lfe
2026-08-04 17:25:40 -04:00
parent 0cf208b80a
commit b1fdaced9f
4 changed files with 42 additions and 11 deletions
+14 -3
View File
@@ -30,9 +30,10 @@
// its token, so the token is not guessable.
//
// OPERATIONAL SAFEGUARDS
// ask is refused when AI is disabled.
// AI_ENABLED gates the whole subsystem; the tab is hidden when it is false, but hiding
// a link is not access control and the endpoint is reachable directly.
// Every action is refused off HOST1, and ask is refused when AI is disabled.
// AI_ENABLED gates the whole subsystem and vv_is_ai_host() gates the node; the tab is
// hidden when either fails, but hiding a link is not access control and the endpoint is
// reachable directly. The host check sits ahead of the dispatch and answers 404.
//
// Every token is validated as hex before it composes a path.
// vv_ai_job_path() returns null for anything else, and each caller checks. That pattern
@@ -117,6 +118,16 @@ if ($action !== 'poll') {
$_SERVER['REMOTE_ADDR'] ?? '?'));
}
// Host gate, ahead of the dispatch rather than inside each action. Varaverk.page omits the tab
// on any host but HOST1, but a hidden link is not access control and this endpoint is reachable
// directly. Every action is refused rather than just the expensive ones — there is no such thing
// as a read this host is entitled to, since the index and the model are not here.
if (!vv_is_ai_host()) {
http_response_code(404);
echo json_encode(['ok' => false, 'error' => 'AI is not available on this host']);
exit;
}
// ── stats ─────────────────────────────────────────────────────────────────────
if ($action === 'stats') {
echo json_encode(['ok' => true, 'stats' => vv_ai_stats()]);