Gate 'install via git URL' and 'install via pip' with dedicated opt-in
boolean flags (allow_git_url_install / allow_pip_install) in config.ini
[default], fully replacing the security_level term on those surfaces
(REPLACE, not AND — a strict level no longer denies when the flag is on;
a weak level no longer allows when the flag is off).
- glob/manager_server.py: pure predicate is_dedicated_install_allowed
(flag AND loopback, request-time args.listen); REPLACE gates at
/customnode/install/git_url and /customnode/install/pip; batch
unknown-URL arm routes through the same full predicate at the risky
position (loopback term is load-bearing — the middle entry gate has
no network-position term; the entry gate itself stays in force);
unknown-pip in batch stays unconditionally blocked; new
SECURITY_MESSAGE_FLAG_* denial constants name the responsible flag;
security_403_response gains flag_token (comfyui_outdated keeps precedence)
- glob/manager_core.py: register both keys (read via get_bool default-false,
write list, exception fallback); "true"-only truthy; restart-only activation
- js/common.js: 403 dialog copy names the responsible flag at the two
install call sites
- README.md: security-policy docs for both flags (per-surface scope incl.
the batch entry-gate qualifier, REPLACE decoupling, loopback bound,
opt-in config snippet, default-deny + migration note); stale tier lists
corrected against the actual gates
- CHANGELOG.md: opt-in migration note + accepted residual risk (flags
bypass the forced-strong outdated-ComfyUI hardening on loopback,
opt-in only), decoupling claim qualified for the batch entry gate
Tests: unit suite (predicate truth table, REPLACE litmus both directions,
AST binding-proofs against live handlers, subprocess-isolated config
contract) plus a real-server E2E suite that mounts the Manager-under-test
via git worktree (exact-SHA pin, detached) against a real ComfyUI and
exercises both flag surfaces and both arms — deny arms (403 + flag-naming
body/log + no install artifact), git-URL allow arm (real clone), pip allow
arm as a two-phase reservation oracle — with zero-residual self-clean.
Module skips without E2E_COMFYUI_ROOT; unit suite unaffected.
The manager-v4 branch ships the identical policy (shared invariants +
config contract); this tree uses the degraded predicate 'flag AND
loopback' (no personal_cloud-equivalent mode here).
handleFile signature is updated in ComfyUI frontend [handleFile (file: File, openSource?: WorkflowOpenSource, options?: { deferWarnings?: boolean } )]. Using rest parameters to fix and future-proof.