ComfyUI-MSS-Login
An all-in-one security and tooling suite for ComfyUI; built to protect public ComfyUI instances while also adding useful features!
MSS-Login
<p align="center"> <img src="./web/assets/mss_logo.png" width="220" /> </p> <p align="center"> <strong>The next-generation security, governance, permissions, and multi‑user control system for ComfyUI.</strong> </p> <p align="center"> <strong>Version 0.0.3</strong> — Latest release includes Extension Tabs API, IP filtering improvements, and performance optimizations </p>Table of Contents
- Overview
- Key Features
- Architecture
- Installation
- Documentation
- Folder Structure
- RBAC Roles
- UI Enforcement Layer
- Workflow Protection
- IP Rules System
- User Environment Tools
- Settings Panel
- API Endpoints
- Backend Components
- Troubleshooting
- License
Overview
ComfyUI mss_login is a comprehensive security layer that adds:
- Role‑Based Access Control (RBAC)
- UI element gating
- Workflow save/delete blocking
- Transparent user folder isolation
- IP whitelist and blacklist enforcement
- User environment management utilities
- A modern administrative panel with multiple tabs
- Dynamic theme integration with the ComfyUI dark mode
- Live UI popups, toast notifications, and visual enforcement
- NSFW Guard API - Public API for NSFW detection and enforcement
- Gallery integration - Manual image flagging and metadata-based tagging
- Extension Tabs API - Allow other extensions to add custom tabs to the admin panel
It replaces the older Sentinel system with a faster, cleaner, more modular architecture—fully rewritten for reliability and future expansion.
Key Features
🔐 RBAC Security
Four roles: Admin, Power, User, Guest
Each with configurable permissions stored in mss_login_groups.json.
🚫 Save & Delete Workflow Blocking
Non‑privileged roles cannot:
- Save workflows
- Export workflows
- Overwrite existing workflows
- Delete workflow files
All blocked actions trigger:
- A server‑side 403
- A UI toast popup explaining the denial
👁️ Dynamic UI Enforcement
mss_login hides or disables:
- Top‑menu items
- Sidebar tabs
- Settings categories
- Extension panels
- File menu operations
Enforcement occurs every 1 second to catch late‑loading UI elements.
🌐 IP Filtering System
Complete backend implementation:
- Whitelist mode
- Blacklist mode
- Live editing in mss_login settings tab
- Persistent storage via
ip_filter.py
🗂️ User Environment Tools
From user_env.py:
- Purge a user’s folders
- List user-owned files
- Promote user workflow to default (all user view)
- Delete single user workflow
- Toggle gallery‑folder mode
🖥️ Transparent Themed Admin UI
The administrative modal features:
- Transparent blurred glass background
- Neon accent tabs
- Integrated logo watermark
- Scrollable permission tables
- Responsive layout
🔧 Watcher Middleware
A new middleware that detects:
- Forbidden workflow saves
- Forbidden deletes And triggers UI-side toast popups through a custom fetch wrapper.
🛡️ NSFW Guard API
A comprehensive public API that allows other ComfyUI extensions to:
- Check user NSFW viewing permissions
- Validate image tensors, PIL Images, or file paths for NSFW content
- Integrate NSFW protection into custom nodes and extensions
- Metadata-based tagging system - Images are tagged with NSFW metadata stored alongside files
- Gallery integration endpoint -
/mss-login-gallery/mark-nsfwfor manual image flagging - Automatic scanning - Background scanning of output directory with caching
- Per-user enforcement - SFW restrictions apply per-user based on role permissions
See API_USAGE.md for complete documentation and examples.
Quick Example:
from api import check_tensor_nsfw, is_sfw_enforced_for_user
# In your custom node
if is_sfw_enforced_for_user():
if check_tensor_nsfw(image_tensor):
# Block or replace NSFW content
image_tensor = torch.zeros_like(image_tensor)
Gallery Integration:
// Mark an image as NSFW from gallery UI
fetch("/mss-login-gallery/mark-nsfw", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
filename: "image.png",
is_nsfw: true,
score: 1.0,
label: "manual",
}),
});
Architecture
ComfyUI
│
├── mss_login Core
│ ├── access_control.py → RBAC, path blocking, folder isolation
│ ├── __init__.py → Route registration, middleware setup
│ ├── api.py → NSFW Guard API (public interface)
│ ├── globals.py → Shared server instances, route table
│ ├── constants.py → Configuration paths
│ ├── routes/
│ │ ├── auth.py → Login/Register/Token endpoints
│ │ ├── admin.py → User & Group management, NSFW admin tools
│ │ ├── user.py → User environment, mark-nsfw endpoint
│ │ ├── static.py → Asset serving
│ │ └── workflow_routes.py → Workflow protection, NSFW enforcement
│ ├── utils/
│ │ ├── ip_filter.py → Whitelist/blacklist system
│ │ ├── user_env.py → User folder management
│ │ ├── sanitizer.py → Input scrubbing
│ │ ├── logger.py → Logging hooks
│ │ ├── timeout.py → Rate limiting
│ │ ├── sfw_intercept/
│ │ │ ├── nsfw_guard.py → NSFW detection, metadata tagging
│ │ │ └── node_interceptor.py → Node-level image interception
│ │ └── reactor_sfw_intercept.py → ReActor SFW patch
│ └── web/
│ ├── js/mss_login_setting.js → UI enforcement + settings panel
│ ├── css/mss-login.css → Themed UI
│ └── assets/mss_logo.png
│
└── ComfyUI (upstream)
Installation
- Extract mss_login into:
ComfyUI/custom_nodes/ComfyUI-MSS-Login/
-
Restart ComfyUI. On first load, dependencies are installed automatically (UV first, pip fallback) into ComfyUI's Python environment when
auto_install_depsis enabled (default). SetAUTO_INSTALL_DEPS=0or"auto_install_deps": falseinconfig.jsonto disable. -
On first launch, register the initial admin.
-
Open settings → mss-login to configure.
See docs/guide/installation.md for manual install commands and platform-specific requirements files.
Documentation
Full documentation (installation, configuration, API reference, and Extension API for integrating the node in your projects) is built with MkDocs and the Material theme. It is available in the docs/ folder and can be published to GitHub Pages or any static host.
Building the docs locally
From the project root:
pip install mkdocs "mkdocs-material"
python scripts/build_docs.py
mkdocs build
mkdocs serve
Then open http://127.0.0.1:8000. The script scripts/build_docs.py regenerates the API reference (HTTP endpoints) and Extension API (NSFW Guard Python API) from the source code.
Extending the node
- HTTP API — See the generated API Reference for all custom endpoints (auth, admin, user, MFA, recovery). For workflow and intercepted paths, see Workflow & intercepted.
- Headless JWT session — Use WebSocket and REST only (no HTML) with a valid JWT to run ComfyUI headless; no loading page or full UI required.
- Python Extension API — Use the NSFW Guard API from other ComfyUI extensions to check or tag NSFW content.
- Overview — Extending the node summarizes how to use both the HTTP and Python APIs in your projects.
When the repository has GitHub Pages enabled and the Docs workflow runs on main or production, the site is deployed automatically.
Folder Structure
mss_login/
│
├── __init__.py → Main entry point, route registration
├── api.py → NSFW Guard API (public interface)
├── globals.py → Shared server instances, route table
├── constants.py → Configuration paths
├── access_control.py → RBAC, path blocking, folder isolation
│
├── routes/
│ ├── auth.py → Login/Register/Token endpoints
│ ├── admin.py → User & Group management, NSFW admin tools
│ ├── user.py → User environment, mark-nsfw endpoint
│ ├── static.py → Asset serving
│ └── workflow_routes.py → Workflow protection, NSFW enforcement
│
├── utils/
│ ├── ip_filter.py → Whitelist/blacklist system
│ ├── user_env.py → User folder management
│ ├── sanitizer.py → Input scrubbing
│ ├── logger.py → Logging hooks
│ ├── timeout.py → Rate limiting
│ ├── sfw_intercept/
│ │ ├── nsfw_guard.py → NSFW detection, metadata tagging
│ │ └── node_interceptor.py → Node-level image interception
│ └── reactor_sfw_intercept.py → ReActor SFW patch
│
├── web/
│ ├── js/mss_login_setting.js → UI enforcement + settings panel
│ ├── css/mss-login.css → Themed UI
│ └── assets/mss_logo.png
│
└── users/
├── users.json
└── mss_login_groups.json
RBAC Roles
| Role | Description | | --------- | ---------------------------------------------------------------------- | | Admin | Full access to all ComfyUI and mss_login features. | | Power | Elevated user with additional permissions but no admin panel access. | | User | Standard user who can run workflows but cannot modify system behavior. | | Guest | Fully restricted by default—cannot run, upload, save, or manage. |
Permissions are stored in:
users/mss_login_groups.json
and editable through the settings panel.
UI Enforcement Layer
mss_login dynamically modifies the UI by:
- Injecting CSS rules to hide elements
- Removing menu entries (Save, Load, Manage Extensions)
- Blocking iTools, Crystools, rgthree, ImpactPack for restricted roles
- Guarding PrimeVue dialogs (Save workflow warnings)
- Intercepting hotkeys (Ctrl+S, Ctrl+O)
All logic is contained in:
web/js/mss_login_setting.js
Workflow Protection
If a user lacking permission tries to save:
- Backend blocks the operation (
can_modify_workflows) - watcher.py detects the 403 with code
"WORKFLOW_SAVE_DENIED" - UI shows a centered toast popup:
“You do not have permission to save workflows.”
Same for delete operations.
IP Rules System
Located in:
utils/ip_filter.py
Features
- Whitelist mode: Only listed IPs allowed
- Blacklist mode: Block specific IPs (permanent or temporary)
- Configurable through new “IP Rules” tab in settings
- Temporary bans: Auto-bans from failed logins expire after a configurable period (default 24 hours;
blacklist_expiry_hoursin config). Manual temporary bans can be set in the admin IP Rules tab. - Permanent bans: Database-only (no JSON file); add or remove via the ComfyUI admin IP Rules tab.
- IP lists are stored in the same database as users (SQLite, PostgreSQL, or MySQL).
- Changes applied instantly to middleware
User Environment Tools
From:
utils/user_env.py
Features:
- Purge a user’s input/output/temp folders
- List all user-bound files
- Toggle whether their folder functions as a gallery
Exposed through the “User Env” tab in the mss_login settings modal.
Settings Panel
Access via: Settings → mss_login
Tabs:
- Users & Roles
- Permissions & UI
- IP Rules
- User Environment
- NSFW Management
Extension Tabs API
Other ComfyUI extensions can register custom tabs in the mss_login admin panel to manage their own permissions and settings. See EXTENSION_TABS_API.md for complete documentation.
Quick Example:
window.mss_loginAdminTabs.register({
id: "myextension",
label: "My Extension",
order: 50,
render: async (container, context) => {
const { usersList, groupsConfig, currentUser } = context;
container.innerHTML = `<h3>My Extension Settings</h3>`;
// Render your content here
},
});
Additional UI Features
- Integrated logout button in the settings entry
- Transparent blurred panel
- Neon-accented tab bar
- Logo watermark in top-right
API Endpoints
NSFW Guard API (Public)
The NSFW Guard API provides programmatic access to NSFW detection and enforcement. See API_USAGE.md for complete documentation.
Key Functions:
check_tensor_nsfw(images_tensor, threshold=0.5)- Check image tensorscheck_image_path_nsfw(image_path, username=None)- Check image filescheck_pil_image_nsfw(pil_image, threshold=0.5)- Check PIL Imagesis_sfw_enforced_for_user(username=None)- Check user restrictionsset_image_nsfw_tag(image_path, is_nsfw, score=1.0, label="manual")- Tag imagesget_image_nsfw_tag(image_path)- Get existing tags
Gallery Integration Endpoint
POST /mss-login-gallery/mark-nsfw
Manually mark an image as NSFW or SFW. Designed for integration with gallery extensions.
Request Body:
{
"filename": "image.png",
"is_nsfw": true,
"score": 1.0, // optional, default 1.0
"label": "manual" // optional, default "manual"
}
Response:
{
"status": "ok",
"message": "Image marked as NSFW",
"filename": "image.png",
"is_nsfw": true
}
Features:
- Recursively searches output directory subdirectories
- Security checks prevent path traversal
- Integrates with metadata tagging system
- Returns 404 if file not found, 403 for invalid paths
Authentication Endpoints
POST /mss-login/api/login - User login
POST /mss-login/api/register - User registration
POST /mss-login/api/guest-login - Guest login
POST /mss-login/api/refresh-token - Token refresh
Admin Endpoints
GET/PUT /mss-login/api/users - User management
GET/PUT /mss-login/api/groups - Group/permission management
PUT /mss-login/api/ip-lists - IP whitelist/blacklist
POST /mss-login/api/nsfw-management - NSFW admin tools (scan, fix, clear)
User Environment Endpoints
POST /mss-login/api/user-env - User folder operations (purge, list, promote)
Extension Integration
Extension Tabs API - JavaScript API for extensions to add custom tabs to the admin panel. See EXTENSION_TABS_API.md for complete documentation.
Backend Components
__init__.py
- Main entry point for ComfyUI extension
- Route registration and middleware setup
- Server instance initialization
api.py
- NSFW Guard API - Public interface for other extensions
- Functions:
check_tensor_nsfw(),check_image_path_nsfw(),is_sfw_enforced_for_user() - Metadata tagging:
set_image_nsfw_tag(),get_image_nsfw_tag() - User context management for worker threads
access_control.py
- Folder isolation
- RBAC
- Middleware for blocking paths
- Workflow protection
- Extension gating
routes/auth.py
- JWT authentication endpoints
- Login, registration, token refresh
- Guest login support
routes/admin.py
- User & group management
- Permission editing
- NSFW management tools (scan, fix, clear)
- IP rules management
routes/user.py
- User environment operations
- Gallery integration:
/mss-login-gallery/mark-nsfwendpoint - File management (purge, list, promote workflows)
routes/workflow_routes.py
- Workflow save/delete protection
- Global NSFW enforcement on
/viewendpoint - Workflow listing and loading
routes/static.py
- Asset serving (CSS, JS, images)
- Logo and UI resources
utils/sfw_intercept/nsfw_guard.py
- NSFW detection using AI models
- Metadata-based tagging system
- Background scanning and caching
- Per-user enforcement logic
utils/sfw_intercept/node_interceptor.py
- Node-level image interception
- Real-time NSFW blocking in custom nodes
utils/reactor_sfw_intercept.py
- ReActor extension SFW patch
- Per-user SFW enforcement for face swap operations
utils/ip_filter.py
- Whitelist & blacklist logic
- Persistent storage
utils/user_env.py
- Folder operations
- Metadata tools
- User file management
Troubleshooting
Missing Logo
Ensure the file exists:
mss-login/web/assets/mss_logo.png
UI Not Updating
Clear browser cache or disable caching dev tools.
Guest cannot run workflows
Check:
can_run = true
in mss_login_groups.json.
mark-nsfw endpoint returns 404
- Ensure the image file exists in the output directory or subdirectories
- Check that the filename doesn't contain path traversal characters (
..,/,\) - Verify the file is within the output directory (security check)
NSFW Guard API not working
- Ensure
ComfyUI-mss_loginis loaded before your extension - Check that the API is available:
from api import is_available; print(is_available()) - Verify user context is set in worker threads using
set_user_context()
NSFW tags not persisting
- Check that metadata files (
.nsfw_metadata.json) are being created alongside images - Verify write permissions in the output directory
- Ensure metadata files aren't being deleted by cleanup scripts
DEBUG_MODE for token / "Unable to connect to server" issues
When using API tokens (e.g. Comfy Portal iOS) and seeing "Unable to connect to server", enable debug logging to see where the request is blocked (remote API guard, JWT/token validation, or access control).
- Environment (Docker/Compose): set
DEBUG_MODE=1orDEBUG_MODE=truein your env or Compose file. - Config: in
config.jsonset"debug_mode": true. - Logs are written to
.cursor/debug.log(NDJSON). Check forlocationvalues:remote_api_guard(blocked before auth),jwt_auth(token not found or invalid),access_control(403 after auth). - 401 responses include a
debughint when DEBUG_MODE is on. Do not leave DEBUG_MODE enabled in production.
API token "not found or expired"
If the client sends a Bearer token but the server returns "API token not found or expired", the token is not in this server's token store. Generate the token on the same ComfyUI instance (and same container/host) that the client connects to. In Docker, ensure the database (unified SQLite file, PostgreSQL, or MySQL) is on a persisted volume so tokens survive restarts and are the same instance the client hits.
Unified database and encrypted SQLite
-
Single database: Users, API tokens, sessions, lockout, IP whitelist/blacklist, and shared items use one SQLite file, one PostgreSQL database, or one MySQL database (config:
users_dbinconfig.json). The default SQLite path isdata/mss_login_data.dbunder the data directory. Token storage uses the same DB; set token storage backend to SQLite, PostgreSQL, or MySQL in Settings. Passwords for PostgreSQL and MySQL are read from environment only (USERS_DB_PASSWORD,POSTGRES_PASSWORD, orMYSQL_PASSWORD). If you had an existingdata/users.db, the first run migrates it todata/mss_login_data.dband updates config automatically. -
Encrypted SQLite: Encryption at rest (SQLCipher) applies only to SQLite. To encrypt the SQLite file with a key derived from
SECRET_KEY, setencryption_levelinusers_dbtolow,standard, orsecure(Settings → Users DB). Requires argon2-cffi (pip install argon2-cffi) and, for encryption at rest, sqlcipher3 with a system SQLCipher build (pip install sqlcipher3; see SQLCipher for your OS). Ifencryption_levelis set but sqlcipher3 is not installed, startup fails with a clear message. -
Base URL: Set
HOST_BASE_URL(e.g.https://comfy.example.com) when behind a reverse proxy so RSS and links use the correct host. If unset, the URL is detected from the first admin or owner connection and stored in the database.
SECRET_KEY and recovery
- Unset SECRET_KEY: If the
SECRET_KEYenvironment variable is not set, a random key is used and persisted tousers/.ephemeral_secret_key(do not commit this file). Sessions and MFA data use this key until restart. - Setting a permanent SECRET_KEY: When you later set
SECRET_KEYin the environment and restart, the extension will automatically migrate TOTP secrets from the ephemeral key to the new key and then remove the ephemeral file. No manual action needed if the file is still present. - Recovery mode: If the ephemeral file was deleted or migration failed, users with MFA may be unable to log in. Enable recovery mode: set
RECOVERY_MODE=1, then from an allowed host (default: localhost only), sendPOST /api/mss-login/recovery/reset-mfa. This clears MFA for all users so they can log in with password and re-enroll MFA. Override allowed hosts withRECOVERY_MODE_HOSTorRECOVERY_MODE_HOST(comma-separated IPs). Recovery is only accessible whenRECOVERY_MODEis enabled and the client IP is in the allowed list.
License
Please refer to the license file found under the readme folder, here: LICENSE.md
Changelog — MSS-Login
All notable changes to the MSS-Login project are documented here. This project follows a semantic-style versioning flow adapted for active development.
Per-version notes live under readme/changelogs/.
Automated releases (CI)
The Create Release workflow prepares each publish:
- Resolves the version (manual input, auto patch bump from the latest tag, or
release/X.Y.Zbranch name). - Runs
scripts/release_prepare.pyto syncpyproject.tomland createreadme/changelogs/X.Y.Z.mdwhen missing. - Builds bullets from
git logsince the previous semver tag (plus optional workflow inputs). - Commits to
release/X.Y.Z, creates the GitHub release, and triggers Publish to ComfyUI registry.
Optional workflow_dispatch inputs: changelog_title, changelog_notes. You do not need to pre-create changelog files; if one already exists for that version, CI leaves it unchanged.
publish.yml verifies pyproject.toml matches the release branch before registry publish so version detection stays aligned with tags.
Changlog
A changelog can be found in the corresponding 'CHANGES.md' file in the readme folder. All changes are documented there.
Changelogs are dynamically generated and put in a subfolder 'changelogs' in the readme folder, in versioned order by the version number (e.g. '0.0.3.md', '0.0.2.md', etc.)