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:
2026-10-06 11:36:30 +02:00
parent 2914d860b1
commit 6802cd2203
19 changed files with 391 additions and 26 deletions
+12 -1
View File
@@ -6,6 +6,7 @@ import { useState } from "react"
import { type ApiError, ModulesService } from "@/client"
import { InfoTip } from "@/components/Flow/SidePanel"
import { Button } from "@/components/ui/button"
import useAuth from "@/hooks/useAuth"
import useCustomToast from "@/hooks/useCustomToast"
import { handleError } from "@/utils"
@@ -32,6 +33,9 @@ function Modules() {
})
const queryClient = useQueryClient()
const { showSuccessToast, showErrorToast } = useCustomToast()
// A package runs its own code on install, so installing is a superuser's.
const { user } = useAuth()
const mayInstall = Boolean(user?.is_superuser)
// Null until the field is touched, so what is stored shows through until
// someone actually starts editing it.
const [draft, setDraft] = useState<string | null>(null)
@@ -84,7 +88,14 @@ function Modules() {
</p>
</div>
{adopted ? null : (
{adopted ? null : !mayInstall ? (
<p
className="text-sm text-muted-foreground"
data-testid="modules-locked"
>
Only a superuser can install packages.
</p>
) : (
<section className="grid gap-3">
<h2 className={SECTION}>Requirements</h2>
<textarea