mcp: per-user connector access control with deny-by-default grants
Nightly Build / build (push) Successful in 6m33s

This commit is contained in:
2026-07-21 20:48:56 +01:00
parent c8e4cb4384
commit 17f5769e0d
11 changed files with 503 additions and 8 deletions
+15
View File
@@ -12,6 +12,7 @@ pub mod known_tools;
pub mod llm_requests;
pub mod llm_request_payloads;
pub mod mcp_catalog;
pub mod mcp_catalog_access;
pub mod mcp_events;
pub mod mcp_global_access;
pub mod mcp_global_servers;
@@ -612,6 +613,20 @@ async fn create_registry_tables(pool: &SqlitePool) -> Result<()> {
.execute(pool)
.await?;
// Which users the admin has authorized to activate each per-user catalog
// connector (the catalog twin of `mcp_global_access`; deny-by-default — no row
// = no access). `catalog_name` FK is registry→registry (both in this file),
// allowed. Supersedes `mcp_catalog.role_filter` as the access gate.
sqlx::query(
"CREATE TABLE IF NOT EXISTS mcp_catalog_access (
catalog_name TEXT NOT NULL REFERENCES mcp_catalog(name) ON DELETE CASCADE,
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
PRIMARY KEY (catalog_name, user_id)
)",
)
.execute(pool)
.await?;
// Capability grants per role (blueprint §14). A single indexed lookup instead
// of parsing `roles.attrs`. `admin` implicitly holds every capability (checked
// in code), so only non-admin roles need rows here.