Make changing engine-run code superuser-only
Writing node source, installing modules and any flow save that adds, retypes or repoints a code node (Function, Command), edits a Command node's settings or changes a node's resources.env now answer 403 for everyone but a superuser. MCP tools and the assistant reach the same routes, so they inherit the gate. Node types report runs_code. The editor shows code read-only with a note, disables a Command node's settings, leaves code nodes and reusable nodes out of the palette and paste, and the Modules page offers no install.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""The MCP endpoint: who it lets in, and what happens once they are in."""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from collections.abc import Awaitable, Callable, Generator
|
||||
from datetime import timedelta
|
||||
@@ -11,6 +12,7 @@ import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlmodel import Session
|
||||
|
||||
from fluksio.api.deps import CODE_IS_SUPERUSERS
|
||||
from fluksio.core import security
|
||||
from fluksio.core.config import settings
|
||||
from fluksio.main import app
|
||||
@@ -170,3 +172,31 @@ def test_revoking_an_agent_stops_the_token_it_already_holds(
|
||||
before, after = over_mcp(block)
|
||||
assert before.status_code == 200
|
||||
assert after.status_code == 401
|
||||
|
||||
|
||||
def test_an_agent_cannot_write_code_its_person_may_not(
|
||||
over_mcp,
|
||||
client: TestClient,
|
||||
normal_user_token_headers: dict[str, str],
|
||||
agent: uuid.UUID,
|
||||
) -> None:
|
||||
"""The tools call the same routes, so an agent inherits the code gate."""
|
||||
me = client.get(
|
||||
f"{settings.API_V1_STR}/users/me", headers=normal_user_token_headers
|
||||
).json()
|
||||
assert me["is_superuser"] is False
|
||||
token = mcp_token(uuid.UUID(me["id"]), agent)
|
||||
|
||||
async def block(http: httpx.AsyncClient) -> httpx.Response:
|
||||
return await http.post(
|
||||
"/mcp",
|
||||
**rpc(
|
||||
token,
|
||||
"tools/call",
|
||||
name="save_node_source",
|
||||
arguments={"name": "any", "node_id": "fn", "code": "import os"},
|
||||
),
|
||||
)
|
||||
|
||||
answer = json.loads(over_mcp(block).json()["result"]["content"][0]["text"])
|
||||
assert answer == {"error": CODE_IS_SUPERUSERS, "status": 403}
|
||||
|
||||
Reference in New Issue
Block a user