mavweb: handler tests + gate DisableTool at step-up
- handlers_test.go: first tests for cmd/mavweb (feature-ranking #2). Covers the /tools enable/disable surface (arg parsing, error mapping, html escaping) and the webauthn handler contracts (method guards, malformed input). 14 cases. Verified the enable path is genuinely gated: an un-asserted call fails at the mavend IPC boundary (Requirement(EnableTool)=AuthStepUp), so mavweb stays a trust-nothing pass-through and core mediates. - policy.go: DisableTool now also requires AuthStepUp. It mutates the same tool allowlist as EnableTool and is a lever to silence a security-relevant tool; gating allowlist mutation uniformly beats a split rule. ProposeTool stays maven-callable (no passkey). Corrects the stale api.go comment that claimed all three gated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,10 +45,13 @@ const (
|
||||
// which the vet check in dispatch catches via Method existence, not auth).
|
||||
func Requirement(m ipc.Method) Authority {
|
||||
switch m {
|
||||
case ipc.MethodEnableTool:
|
||||
// Registration-enable is privilege escalation: it moves the boundary
|
||||
// (adds a runnable capability). Human-only, step-up asserted — never a
|
||||
// module or the voice/chat path. maven can propose but never enable.
|
||||
case ipc.MethodEnableTool, ipc.MethodDisableTool:
|
||||
// Both mutate the tool allowlist — the boundary. Enable adds a runnable
|
||||
// capability (privilege escalation); disable removes one (fail-safe
|
||||
// direction, but still an allowlist mutation and a lever an attacker
|
||||
// could pull to silence a security-relevant tool). Human-only, step-up
|
||||
// asserted — never a module or the voice/chat path. maven can propose
|
||||
// (MethodProposeTool, no step-up: she has no passkey) but never en/disable.
|
||||
return AuthStepUp
|
||||
case ipc.MethodWriteFact:
|
||||
return AuthWrite
|
||||
|
||||
+3
-1
@@ -221,7 +221,9 @@ type CoreAPI interface {
|
||||
// returns whether a new proposal was written. EnableTool fills cmd +
|
||||
// destructive and flips status to 'enabled'. DisableTool reverts an
|
||||
// enabled tool back to proposed (it stays in the store, won't run).
|
||||
// All three gate at AuthStepUp. LookupTool/ListTools read them.
|
||||
// Enable/DisableTool gate at AuthStepUp (allowlist mutation, human-only);
|
||||
// ProposeTool is maven-callable (no step-up — she has no passkey).
|
||||
// LookupTool/ListTools read them.
|
||||
ProposeTool(ctx context.Context, name, utterance string, ts time.Time) (bool, error)
|
||||
EnableTool(ctx context.Context, name string, cmd []string, destructive bool, ts time.Time) error
|
||||
DisableTool(ctx context.Context, name string) error
|
||||
|
||||
Reference in New Issue
Block a user