From f1c47bc9ef1faafb884d0c3a71c5da8e96e67d21 Mon Sep 17 00:00:00 2001 From: Ghost Scripter Date: Fri, 9 Oct 2026 18:55:35 +0530 Subject: [PATCH] chore(openapi): deny the admin memory reads at the raw transport Sync against tinyhumansai/backend#1414's spec: the five GET /admin/memory/* routes (overview, storage, top-tenants, tenants/{userId}, model-usage) join UNEXPOSED_ROUTES. No typed method. Ratchets: UNEXPOSED_ROUTES 59 -> 64, excludedAdminOperationCount 47 -> 52. --- api/tinyhumans.backend.json | 6 +++--- src/generated_public_routes.rs | 5 +++++ src/lib_exclusion_tests.rs | 6 +++++- tests/openapi_sync.rs | 7 ++++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/api/tinyhumans.backend.json b/api/tinyhumans.backend.json index 2011e1b..92eaf2a 100644 --- a/api/tinyhumans.backend.json +++ b/api/tinyhumans.backend.json @@ -8,11 +8,11 @@ "url": "https://api.tinyhumans.ai/swagger.json", "title": "TinyHumans API", "version": "1.0.0", - "pathCount": 289, - "totalOperationCount": 321, + "pathCount": 294, + "totalOperationCount": 326, "operationCount": 266, "supplementalOperationCount": 13, - "excludedAdminOperationCount": 47, + "excludedAdminOperationCount": 52, "excludedWebhookOperationCount": 12, "servers": [ "https://api.tinyhumans.ai/", diff --git a/src/generated_public_routes.rs b/src/generated_public_routes.rs index 195e086..60a16f9 100644 --- a/src/generated_public_routes.rs +++ b/src/generated_public_routes.rs @@ -289,6 +289,11 @@ pub(crate) const UNEXPOSED_ROUTES: &[(&str, &str)] = &[ ("POST", "/admin/feedback/triage/{feedbackId}/merge"), ("POST", "/admin/feedback/triage/{feedbackId}/reject"), ("POST", "/admin/feedback/triage/{feedbackId}/reprocess"), + ("GET", "/admin/memory/model-usage"), + ("GET", "/admin/memory/overview"), + ("GET", "/admin/memory/storage"), + ("GET", "/admin/memory/tenants/{userId}"), + ("GET", "/admin/memory/top-tenants"), ("GET", "/admin/settings"), ("PATCH", "/admin/settings/{key}"), ("POST", "/admin/users/{userId}/credits"), diff --git a/src/lib_exclusion_tests.rs b/src/lib_exclusion_tests.rs index d4cb690..4550b35 100644 --- a/src/lib_exclusion_tests.rs +++ b/src/lib_exclusion_tests.rs @@ -63,7 +63,11 @@ fn every_admin_and_webhook_route_is_rejected_by_the_raw_transport_gate() { // The telemetry ingestion endpoint (OTEL / Langfuse) does NOT belong // here: it takes a normal user bearer token, not a service token, so // it stays in PUBLIC_ROUTES. - assert_eq!(UNEXPOSED_ROUTES.len(), 59); + // 59 -> 64: the five `GET /admin/memory/*` reads (`overview`, `storage`, + // `top-tenants`, `tenants/{userId}` and the new `model-usage`). The first + // four were already on backend `main` but never synced here; admin-only, + // so blocked at the raw transport and given no typed method. + assert_eq!(UNEXPOSED_ROUTES.len(), 64); for (method, template) in UNEXPOSED_ROUTES { let concrete_path = template .split('/') diff --git a/tests/openapi_sync.rs b/tests/openapi_sync.rs index c436120..659598e 100644 --- a/tests/openapi_sync.rs +++ b/tests/openapi_sync.rs @@ -244,7 +244,12 @@ fn generated_rust_routes_match_the_public_manifest() { // not name them — and the SDK refuses that whole prefix structurally. The // Langfuse telemetry receiver is not counted here: it is ordinary public // API (user bearer token), so it stays in the public surface above. - assert_eq!(manifest["source"]["excludedAdminOperationCount"], 47); + // + // 47 -> 52: the five `GET /admin/memory/*` reads (`overview`, `storage`, + // `top-tenants`, `tenants/{userId}`, and the new `model-usage`), the + // admin service token's memory aggregates. Four were already on backend + // `main` but never synced; none is public. + assert_eq!(manifest["source"]["excludedAdminOperationCount"], 52); assert_eq!(manifest["source"]["excludedWebhookOperationCount"], 12); // 206 -> 208: the two new public opencompany routes above // (`GET /opencompany/companies` and `POST /opencompany/instances/{slug}/update`).