This guide is for the people who deploy, operate, secure, and extend Flowise: platform admins, DevOps/SRE, backend developers, and architects. It documents the system architecture, the full configuration surface, deployment strategies (including high-scale queue mode), security hardening, the data model, operations, and the custom-node SDK for developers extending the platform.
For builder-facing usage (the visual canvas, node types, RAG, deploying a chatbot), see the Flowise User Guide. This guide assumes that knowledge and goes underneath it.
Note
Scope discipline. Flowise is a workflow-automation platform that ships hundreds of integration nodes. This guide documents the platform — server architecture, the node-loading/execution engine, configuration, and the SDK contract every node implements — not each of the 300+ individual integrations. Once you understand
INodeandNodesPool, every integration is the same shape.
1. Executive summary
| Attribute | Value |
|---|---|
| Project | FlowiseAI/Flowise |
| Version | 3.1.2 |
| License | Apache 2.0 (core) + FlowiseAI Commercial License (enterprise modules under packages/server/src/enterprise) |
| Language | TypeScript (Node.js backend, React frontend) |
| Repository model | pnpm + Turborepo monorepo, six published/internal packages |
| Runtime | Node.js >= 20 (Docker image uses Node 24) |
| Backend | Express 4 + TypeORM |
| Databases | SQLite (default), PostgreSQL, MySQL, MariaDB |
| Frontend | React 18 + MUI + ReactFlow + Redux Toolkit (Vite build) |
| Core engine | LangChain JS 1.x + LlamaIndex; orchestrated by Flowise's own NodesPool/AgentFlow |
| Scaling | Optional queue mode (BullMQ + Redis) with horizontal workers |
| Observability | Winston logging, Prometheus / OpenTelemetry metrics, PostHog telemetry |
What it is: Flowise turns a visual graph of nodes into an executable LLM application — a chatbot, an autonomous agent, or a REST API. The server loads every node into an in-memory pool at boot, instantiates the graph per request, executes it (optionally on background workers), and streams results over SSE.
Operational headline: a single container with SQLite is enough for evaluation and small teams. For production, switch to PostgreSQL, externalize storage and secrets, and enable queue mode to scale execution horizontally.
2. Architecture
2.1 Monorepo layout
Flowise is a single repository with multiple packages built by Turborepo:
| Package | npm name | Role |
|---|---|---|
packages/server |
flowise |
Express API + execution engine + CLI (oclif). The deployable backend. |
packages/ui |
flowise-ui |
React single-page app (the visual builder). Served by the backend. |
packages/components |
flowise-components |
All integration nodes + credentials + shared runtime helpers. |
packages/api-documentation |
flowise-api |
Swagger-UI server generated from Express JSDoc. |
packages/agentflow |
@flowiseai/agentflow |
Embeddable React component for building/visualizing agent workflows. |
packages/observe |
@flowiseai/observe |
Embeddable React component for observing executions/evaluations. |
The first three are the product; the last three are publishable building blocks. flowise (server) depends on flowise-components and flowise-ui as workspace dependencies, so a single flowise start serves the API, the UI, and the node library together.
2.2 Runtime topology
┌──────────────────────────────────────────┐
Browser / API client │ flowise (server) │
│ │ │
▼ │ Express app │
┌───────────┐ HTTP/SSE│ ├── /api/v1/* routers (66 sub-routers) │
│ React UI │◄────────►│ ├── auth (passport) + RBAC middleware │
│ (flowise- │ │ ├── NodesPool (all nodes, in memory) │
│ ui) │ │ ├── execution engine (build + run graph)│
└───────────┘ │ ├── SSEStreamer (token streaming) │
│ ├── AbortControllerPool (cancel runs) │
│ ├── CachePool / RateLimiterManager │
│ └── ScheduleBeat (cron-triggered flows) │
└───────┬───────────────┬──────────────────┘
│ │
┌────────────▼───┐ ┌──────▼───────────────────┐
│ Database │ │ Optional (MODE=queue) │
│ (TypeORM): │ │ BullMQ + Redis │
│ sqlite/pg/ │ │ ├── QueueManager │
│ mysql/mariadb │ │ ├── prediction workers │
└────────────────┘ │ └── RedisEventSubscriber│
┌────────────────┐ └──────────────────────────┘
│ Object storage │
│ local/s3/gcs/ │ ┌──────────────────────────┐
│ azure │ │ Secrets: file / AWS SM │
└────────────────┘ └──────────────────────────┘
2.3 Boot sequence
flowise start → BaseCommand.init() (loads .env, maps --FLAGS to process.env) → DataSource.init() → Server.start(). The App.initDatabase() sequence (in packages/server/src/index.ts) is the authoritative startup order:
- DataSource initialize — connect via TypeORM.
- Run migrations — each in its own transaction; schema is auto-migrated on every boot.
- IdentityManager — auth/enterprise identity (users, orgs, workspaces, plan features).
- NodesPool — scan
flowise-componentsand load every node class into memory. - AbortControllerPool — registry for cancelling in-flight predictions.
- Encryption key — load/generate the key used to encrypt stored credentials.
- Auth secrets — resolve JWT/session/hash secrets (env → AWS Secrets Manager → filesystem).
- Rate limiters — built per-chatflow from saved rate-limit config.
- CachePool + UsageCacheManager — response/usage caches.
- QueueManager — only when
MODE=queue; wires BullMQ queues and the Bull-Board dashboard. - Metrics provider — Prometheus or OpenTelemetry, if
ENABLE_METRICS=true. - SSEStreamer — server-sent-events channel for streaming.
- Webhook listener registry + ScheduleBeat — webhook triggers and cron-scheduled flows.
Important
Migrations run automatically at startup against per-dialect migration sets (
packages/server/src/database/migrations/{sqlite,postgres,mysql,mariadb}). Always back up the database before upgrading the image — a new release may add migrations that alter the schema in place.
2.4 The execution engine
When a prediction request arrives:
- The chatflow's saved JSON graph is loaded.
- Nodes are instantiated from
NodesPooland topologically resolved. - Each node's
init()/run()is invoked with resolved inputs and an options bag (session, credentials, callbacks). - Streaming output is pushed through
SSEStreamer; the run is cancellable viaAbortControllerPool. - In
MODE=queue, steps 2–4 run on a worker process; the web process enqueues the job and subscribes to events via Redis.
AgentFlow V2 (in packages/agentflow + packages/components/nodes/agentflow) is Flowise's own orchestration layer for multi-step/branching agents, distinct from the underlying LangChain agent primitives.
3. Requirements
| Component | Requirement | Notes |
|---|---|---|
| Node.js | >= 20 (image: 24-alpine) |
engines.node is pinned to ^24; use current LTS for parity. |
| pnpm | ^10.26.0 |
Source builds only. |
| Database | SQLite / PostgreSQL / MySQL / MariaDB | PostgreSQL recommended for production. |
| Redis | Any 6+ | Required only for MODE=queue. |
| Build memory | 4–8 GB | Docker sets NODE_OPTIONS=--max-old-space-size=8192. |
| Browser engine | Chromium | Bundled in the Docker image for Puppeteer/Playwright loaders. |
4. Configuration mastery
Flowise is configured entirely through environment variables, which can be set in .env, the process environment, the Docker Compose .env, or passed as CLI flags to flowise start (every variable below has a matching --FLAG, defined in packages/server/src/commands/base.ts).
Tip
npx flowise start --PORT=3001 --DATABASE_TYPE=postgres --MODE=queueis equivalent to setting those three env vars. Flags override.env.
4.1 Core & networking
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
HTTP listen port. |
NUMBER_OF_PROXIES |
— | Trusted proxy hop count (behind a load balancer). |
CORS_ORIGINS |
* |
Allowed CORS origins for the API. |
MCP_CORS_ORIGINS |
* |
CORS origins for MCP endpoints. |
IFRAME_ORIGINS |
* |
Origins allowed to embed Flowise in an iframe. |
FLOWISE_FILE_SIZE_LIMIT |
50mb |
Max request/upload body size. |
APP_URL |
http://localhost:3000 |
Public base URL (used in emails/links). |
DISABLE_FLOWISE_TELEMETRY |
— | Set true to disable anonymous usage telemetry. |
SHOW_COMMUNITY_NODES |
— | Show community-contributed nodes in the palette. |
DISABLED_NODES |
— | Comma-separated node names to hide (e.g. bufferMemory,chatOpenAI). |
MODEL_LIST_CONFIG_JSON |
— | Path to a custom model-list config file. |
4.2 Database
| Variable | Default | Purpose |
|---|---|---|
DATABASE_TYPE |
sqlite |
sqlite | postgres | mysql | mariadb. |
DATABASE_PATH |
~/.flowise |
SQLite file location (sqlite only). |
DATABASE_HOST / DATABASE_PORT |
— / 5432 |
Server DB connection. |
DATABASE_NAME / DATABASE_USER / DATABASE_PASSWORD |
flowise / — / — |
Credentials. |
DATABASE_SSL |
false |
Enable TLS to the database. |
DATABASE_SSL_KEY_BASE64 |
— | Base64 self-signed cert for DB TLS. |
DATABASE_REJECT_UNAUTHORIZED |
true |
Reject unauthorized DB TLS certs. |
4.3 Secrets & credential encryption
| Variable | Default | Purpose |
|---|---|---|
SECRETKEY_STORAGE_TYPE |
local |
local (file) or aws (Secrets Manager). |
SECRETKEY_PATH |
~/.flowise |
Where the local encryption key is stored. |
FLOWISE_SECRETKEY_OVERWRITE |
— | Provide the encryption key directly (e.g. from a secret manager). |
SECRETKEY_AWS_ACCESS_KEY / _SECRET_KEY / _REGION / _NAME |
— | AWS Secrets Manager config. |
SECRETKEY_AWS_AUTH_PREFIX |
Flowise |
Prefix for AWS-stored auth secrets. |
Caution
The encryption key decrypts every stored credential. If you lose it, all stored provider keys become unrecoverable and flows that use them break. In production, set
SECRETKEY_STORAGE_TYPE=awsor injectFLOWISE_SECRETKEY_OVERWRITEfrom your secret manager — never bake it into an image.
4.4 Authentication
| Variable | Default | Purpose |
|---|---|---|
JWT_AUTH_TOKEN_SECRET / JWT_REFRESH_TOKEN_SECRET |
— (file/AWS fallback) | JWT signing secrets. Generate with openssl rand -hex 32. |
JWT_ISSUER / JWT_AUDIENCE |
Flowise / Flowise |
JWT claims. |
JWT_TOKEN_EXPIRY_IN_MINUTES |
360 |
Access token lifetime. |
JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES |
43200 |
Refresh token lifetime (30 days). |
EXPRESS_SESSION_SECRET |
— | Session cookie signing secret. |
TOKEN_HASH_SECRET |
— | Hashing secret for stored tokens. |
SECURE_COOKIES |
— | Force secure cookies (HTTPS). |
EXPIRE_AUTH_TOKENS_ON_RESTART |
— | Invalidate all tokens on restart. |
PASSWORD_SALT_HASH_ROUNDS |
10 |
bcrypt cost factor. |
PASSWORD_RESET_TOKEN_EXPIRY_IN_MINS |
15 |
Reset link lifetime. |
INVITE_TOKEN_EXPIRY_IN_HOURS |
24 |
Workspace invite lifetime. |
SMTP: SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASSWORD / SMTP_SECURE / SENDER_EMAIL |
— | Outbound email (invites, resets). |
Authentication is built on Passport with strategies for local login, JWT cookies, and SSO providers (Google, GitHub, Auth0, generic OpenID Connect). The public prediction API authenticates with API keys (managed under the ApiKey entity / /api/v1/apikey).
4.5 Storage
| Variable | Default | Purpose |
|---|---|---|
STORAGE_TYPE |
local |
local | s3 | gcs | azure. |
BLOB_STORAGE_PATH |
~/.flowise/storage |
Local file storage root. |
S3_STORAGE_BUCKET_NAME / S3_STORAGE_ACCESS_KEY_ID / S3_STORAGE_SECRET_ACCESS_KEY / S3_STORAGE_REGION |
— | S3 storage. |
S3_ENDPOINT_URL / S3_FORCE_PATH_STYLE |
— / false |
S3-compatible endpoints (MinIO, etc.). |
GOOGLE_CLOUD_STORAGE_* |
— | GCS bucket + credentials. |
AZURE_BLOB_STORAGE_* |
— | Azure Blob (connection string OR account name + key). |
4.6 Queue mode (scaling)
| Variable | Default | Purpose |
|---|---|---|
MODE |
main |
main (single process) or queue (web + workers). |
QUEUE_NAME |
flowise-queue |
BullMQ queue name. |
WORKER_CONCURRENCY |
100000 |
Max concurrent jobs per worker. |
QUEUE_REDIS_EVENT_STREAM_MAX_LEN |
100000 |
Redis stream cap for events. |
REMOVE_ON_AGE / REMOVE_ON_COUNT |
86400 / 10000 |
Completed-job retention. |
REDIS_URL or REDIS_HOST/REDIS_PORT |
— / localhost:6379 |
Redis connection. |
REDIS_USERNAME / REDIS_PASSWORD |
— | Redis auth. |
REDIS_TLS / REDIS_CERT / REDIS_KEY / REDIS_CA |
— | Redis TLS. |
ENABLE_BULLMQ_DASHBOARD |
— | Expose the Bull-Board queue dashboard. |
4.7 Security
| Variable | Default | Purpose |
|---|---|---|
HTTP_SECURITY_CHECK |
true |
Enforce SSRF/host checks on outbound HTTP from nodes. |
HTTP_DENY_LIST |
— | Additional hosts/CIDRs to block for request nodes. |
PATH_TRAVERSAL_SAFETY |
true |
Block path-traversal in file operations. |
TRUST_PROXY |
— | Express trust-proxy setting behind LBs. |
OAUTH2_SECURITY_CHECK |
true |
Validate OAuth2 token provider domains. |
OAUTH2_ALLOWED_TOKEN_DOMAINS |
— | Extra allowed OAuth2 IdP domains. |
CUSTOM_MCP_SECURITY_CHECK |
true |
Validate Custom MCP server configs. |
CUSTOM_MCP_PROTOCOL |
sse |
sse (safe) or stdio (can run arbitrary commands). |
CUSTOM_MCP_ALLOWED_ENV_VARS |
— (none) | Allowlist of env vars a stdio MCP config may set. |
CUSTOM_MCP_TOOLS_MAX_BYTES |
524288 |
Max size of a custom MCP tool definition. |
TOOL_FUNCTION_BUILTIN_DEP |
crypto,fs |
Node builtins allowed in Custom Function/Tool code. |
TOOL_FUNCTION_EXTERNAL_DEP |
moment,lodash |
External modules allowed in custom code. |
ALLOW_BUILTIN_DEP |
false |
Allow all Node builtins in custom code (dangerous). |
4.8 Logging, metrics, proxy, schedule
| Variable | Default | Purpose |
|---|---|---|
DEBUG |
— | Verbose request logging. |
LOG_PATH |
~/.flowise/logs |
Log directory. |
LOG_LEVEL |
info |
error | warn | info | verbose | debug. |
LOG_SANITIZE_BODY_FIELDS / LOG_SANITIZE_HEADER_FIELDS |
(sensible defaults) | Redact secrets from logs. |
ENABLE_METRICS |
false |
Turn on metrics export. |
METRICS_PROVIDER |
prometheus |
prometheus or open_telemetry. |
METRICS_OPEN_TELEMETRY_METRIC_ENDPOINT / _PROTOCOL |
— / http |
OTel collector endpoint. |
POSTHOG_PUBLIC_API_KEY |
— | Product analytics key. |
GLOBAL_AGENT_HTTP(S)_PROXY / _NO_PROXY |
— | Corporate proxy for all outbound traffic. |
MIN_SCHEDULE_INTERVAL_SECONDS |
60 |
Floor for scheduled-flow cron intervals. |
PUPPETEER_EXECUTABLE_FILE_PATH / PLAYWRIGHT_EXECUTABLE_FILE_PATH |
— | Browser binary for scraping loaders. |
4.9 Enterprise
| Variable | Purpose |
|---|---|
FLOWISE_EE_LICENSE_KEY |
Enterprise license key. |
LICENSE_URL |
License validation endpoint. |
OFFLINE |
Offline/air-gapped license mode. |
WORKSPACE_INVITE_TEMPLATE_PATH |
Custom invite email template. |
5. The data model
TypeORM entities (packages/server/src/database/entities) define the schema. Core (Apache) tables:
| Entity | Holds |
|---|---|
ChatFlow |
A saved flow's graph JSON, type (chatflow/agentflow), deployment + chatbot config, rate limits. |
ChatMessage |
Per-message conversation history, keyed by sessionId. |
ChatMessageFeedback |
Thumbs-up/down feedback on messages. |
Credential |
Encrypted provider secrets. |
Tool |
User-defined custom tools (name, schema, function body). |
Assistant |
OpenAI/custom assistant definitions. |
Variable |
Reusable {{$vars.*}} values. |
DocumentStore / DocumentStoreFileChunk |
Managed knowledge bases and their chunks. |
UpsertHistory |
Record of vector-store upsert operations. |
Lead |
Captured leads from chatbot lead forms. |
Dataset / DatasetRow |
Test datasets for evaluation. |
Evaluation / EvaluationRun / Evaluator |
Quality scoring of flows. |
Execution |
Step-by-step agent run logs. |
CustomTemplate |
Saved flow/tool templates. |
CustomMcpServer |
Registered custom MCP server configs. |
ScheduleRecord / ScheduleTriggerLog |
Cron-scheduled flow definitions and their run logs. |
ApiKey |
API keys for the public prediction API. |
Enterprise tables (packages/server/src/enterprise/database/entities): User, Organization, Role, OrganizationUser, Workspace, WorkspaceUser, LoginMethod, LoginSession, LoginActivity, WorkspaceShared, WorkspaceUsers.
Migrations are maintained separately per dialect under migrations/{sqlite,postgres,mysql,mariadb} and applied automatically on boot.
6. API reference
The API is mounted at /api/v1 (see packages/server/src/routes/index.ts, which composes 66 sub-routers). Authentication: API key (Authorization: Bearer <key>) for the public prediction surface; JWT cookie session for the management API behind the UI. Some routes are gated by plan features via IdentityManager.checkFeatureByPlan(...).
6.1 Most-used endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/prediction/{chatflowId} |
Run a flow (public, API-key auth). |
| POST | /api/v1/internal-prediction |
Run a flow from the UI (session auth). |
| GET/POST/PUT/DELETE | /api/v1/chatflows |
Manage flows. |
| GET | /api/v1/chatmessage/{chatflowId} |
Conversation history. |
| GET/POST/DELETE | /api/v1/credentials |
Manage encrypted credentials. |
| GET/POST | /api/v1/tools |
Manage custom tools. |
| GET/POST | /api/v1/variables |
Manage variables. |
| GET/POST | /api/v1/document-store |
Manage knowledge bases. |
| POST | /api/v1/vector/upsert/{chatflowId} |
Upsert documents into a vector store. |
| GET | /api/v1/executions |
Inspect agent runs. |
| GET/POST | /api/v1/apikey |
Manage API keys. |
| GET | /api/v1/ping |
Health check (used by Docker healthcheck). |
| GET | /api/v1/nodes |
List loaded nodes (from NodesPool). |
| POST | /api/v1/mcp , /api/v1/mcp-server |
MCP endpoint & server management. |
6.2 Enterprise endpoints
/api/v1/auth, /user, /organization, /role (feat:roles), /workspace, /account, /loginmethod, /audit (feat:login-activity), /logs (feat:logs). The account.route (under enterprise/routes) handles registration, email verification, password reset, and billing.
6.3 Interactive docs
Run the flowise-api package (Swagger UI generated from Express JSDoc) for a live, parameter-level API explorer.
7. Deployment
7.1 Docker Compose (recommended baseline)
cd Flowise/docker
cp .env.example .env
# edit .env: set DATABASE_*, secrets, STORAGE_*, etc.
docker compose up -d
The provided docker-compose.yml:
- Pulls
flowiseai/flowise:latest,restart: always. - Maps every config variable from
.envinto the container. - Persists
~/.flowisevia a volume (~/.flowise:/root/.flowise). - Defines a healthcheck hitting
/api/v1/ping.
Warning
The default volume mounts the host's
~/.flowise. For production, pointDATABASE_*at an external PostgreSQL andSTORAGE_TYPEat S3/GCS/Azure so state isn't trapped on one host's disk. The bundled compose also has no TLS — terminate HTTPS at a reverse proxy (Traefik/Nginx/cloud LB) and setSECURE_COOKIES=true,TRUST_PROXY, andNUMBER_OF_PROXIES.
7.2 Production checklist
- [ ]
DATABASE_TYPE=postgreswith managed PostgreSQL (andDATABASE_SSL=true). - [ ]
STORAGE_TYPE=s3|gcs|azurefor durable file storage. - [ ]
SECRETKEY_STORAGE_TYPE=awsor injectedFLOWISE_SECRETKEY_OVERWRITE. - [ ] Strong, externally-managed
JWT_*,EXPRESS_SESSION_SECRET,TOKEN_HASH_SECRET(openssl rand -hex 32). - [ ] HTTPS at the proxy;
SECURE_COOKIES=true;CORS_ORIGINSandIFRAME_ORIGINSlocked to known origins. - [ ]
HTTP_SECURITY_CHECK=true, sensibleHTTP_DENY_LIST(block cloud metadata IPs, internal ranges). - [ ] Custom-code deps restricted (
ALLOW_BUILTIN_DEP=false, tightTOOL_FUNCTION_*_DEP). - [ ] MCP: keep
CUSTOM_MCP_PROTOCOL=sse; onlystdiofor fully trusted operators. - [ ] Backups for the database and the encryption key.
- [ ]
ENABLE_METRICS=truewired to Prometheus/OTel; log shipping configured.
7.3 Scaling with queue mode
For high concurrency, run the web tier and worker tier separately:
# Web process(es) — serve API/UI, enqueue jobs
MODE=queue REDIS_HOST=redis ... npx flowise start
# Worker process(es) — execute flows
MODE=queue REDIS_HOST=redis ... npx flowise worker
The repo ships dedicated compose files for this: docker/docker-compose-queue-prebuilt.yml and docker/docker-compose-queue-source.yml, plus a docker/worker image with its own healthcheck. Scale by adding worker replicas; tune WORKER_CONCURRENCY and job retention (REMOVE_ON_AGE/REMOVE_ON_COUNT). Enable ENABLE_BULLMQ_DASHBOARD to watch the queue via Bull-Board.
Note
The CLI exposes three commands:
flowise start(web/all-in-one),flowise worker(queue worker), andflowise user(user administration). All accept any config variable as a--FLAG.
7.4 Managed platforms
One-click templates exist for AWS, Azure, GCP, Digital Ocean, Railway, Render, Northflank, HuggingFace Spaces, Elestio, Sealos, and RepoCloud. Flowise Cloud is the vendor-hosted option.
8. Security
Flowise executes user-authored graphs and, optionally, user-authored code — so the security model centers on sandboxing untrusted input and constraining outbound access.
8.1 Threat surface & controls
| Surface | Risk | Control |
|---|---|---|
| Custom Tool / Function code | Arbitrary code execution | Runs sandboxed; dependency allowlists (TOOL_FUNCTION_BUILTIN_DEP, TOOL_FUNCTION_EXTERNAL_DEP, ALLOW_BUILTIN_DEP=false). |
| Request/HTTP/scraper nodes | SSRF to internal services & cloud metadata | httpSecurity enforces deny-by-policy (Access to this host is denied by policy.), HTTP_DENY_LIST, DNS-resolution checks, redirect caps. |
| File operations | Path traversal | PATH_TRAVERSAL_SAFETY=true. |
| Custom MCP servers | Arbitrary command execution (stdio) | Default sse; CUSTOM_MCP_ALLOWED_ENV_VARS allowlist; size cap; CUSTOM_MCP_SECURITY_CHECK. |
| Structured-output schemas | Code injection via eval of schema strings |
secureZodParser parses z.object() schemas safely (Schema must start with z.object()). |
| Inbound headers | Header injection | headerValidation (max headers, key/type checks). |
| OAuth2 token providers | Token spoofing | OAUTH2_SECURITY_CHECK + OAUTH2_ALLOWED_TOKEN_DOMAINS. |
| Credentials at rest | Secret theft | Encrypted with the instance key (file/AWS); redacted in logs via LOG_SANITIZE_*. |
| Embedding/iframe | Clickjacking, key leakage | IFRAME_ORIGINS, MCP_CORS_ORIGINS, CSP/iframe security headers. |
8.2 Authentication & authorization
- App access: Passport (local + JWT cookie). SSO via Google, GitHub, Auth0, OpenID Connect.
- API access: API keys (
ApiKeyentity), validated byvalidateAPIKeymiddleware; some URLs are API-key-blacklisted or whitelisted (API_KEY_BLACKLIST_URLS,WHITELIST_URLS). - RBAC (enterprise): Organizations → Workspaces → Roles. Feature gates (
IdentityManager.checkFeatureByPlan) restrict datasets, evaluations, roles, audit logs, etc. by license plan. - Rate limiting: per-chatflow limits via
RateLimiterManager(optionally backed by Redis).
8.3 Known security items
- #6444 — request for CVE assignment for GHSA-jg8m-mc94-2g3x (Critical RCE). Track the advisory and stay on the latest release.
- #6433 — proposed pre-execution trust-verification hook for MCP tool calls.
- #6413 — agent-memory poisoning hardening (OWASP ASI06).
Caution
Treat any Flowise instance that allows untrusted users to author Custom Tools/Functions or Custom MCP
stdioservers as a remote-code-execution surface. Isolate it (dedicated network segment, no cloud-metadata access, least-privilege IAM) and keep dependency allowlists tight.
9. Operations
9.1 Start / stop / health
| Action | How |
|---|---|
| Start (all-in-one) | flowise start / docker compose up -d |
| Start worker | flowise worker |
| Graceful stop | SIGTERM/SIGINT → App.stopApp() (30s force-exit guard) |
| Health check | GET /api/v1/ping (Docker healthcheck polls this) |
| Logs | stdout + LOG_PATH; raise LOG_LEVEL=debug or DEBUG=true |
9.2 Backups
Back up two things together: the database (SQLite file or your Postgres/MySQL dump) and the encryption key (SECRETKEY_PATH file or the AWS secret). Restoring a database without its matching key leaves credentials undecryptable. Also back up BLOB_STORAGE_PATH (or rely on your object store's durability).
9.3 Upgrades
- Read the release notes for breaking changes/migrations.
- Back up DB + key.
- Pull the new image /
pnpm install && pnpm build. - Restart — migrations run automatically.
- Smoke-test
/api/v1/ping, a prediction, and a RAG flow.
9.4 Monitoring
Enable metrics (ENABLE_METRICS=true) and scrape Prometheus (prom-client) or export to an OpenTelemetry collector. Per-node metrics are included by default (METRICS_INCLUDE_NODE_METRICS=true). Watch: prediction latency/error rate, queue depth and worker concurrency (queue mode), DB connections, and event-loop lag (heavy graphs are CPU-bound).
10. Extending Flowise: the custom-node SDK
Every integration is a node implementing the INode contract in packages/components/src/Interface.ts. The loading engine (NodesPool) discovers node classes in flowise-components at boot, so a new node is just a class file that exports a default class with the right shape.
10.1 The INode contract
A node combines descriptive properties with optional inputs, credential, and execution methods:
export interface INodeProperties {
label: string // display name in the palette
name: string // unique internal id
type: string // node type
icon: string // icon asset
version: number // node version (for migrations)
category: string // palette grouping (Chat Models, Tools, ...)
baseClasses: string[] // output types it satisfies (drives anchor compatibility)
description?: string
badge?: string
deprecateMessage?: string
// ...
}
export interface INode extends INodeProperties {
credential?: INodeParams
inputs?: INodeParams[]
output?: INodeOutputsValue[]
loadMethods?: {
[key: string]: (nodeData: INodeData, options?: ICommonObject) => Promise<INodeOptionsValue[]>
}
vectorStoreMethods?: {
upsert: (nodeData, options?) => Promise<IndexingResult | void>
search: (nodeData, options?) => Promise<any>
delete: (nodeData, ids, options?) => Promise<void>
}
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<any>
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<string | ICommonObject>
}
Key concepts:
baseClassesdrive anchor compatibility — a node whosebaseClassesincludesBaseChatModelcan connect to any input that accepts aBaseChatModel. This is how the canvas knows a chat model can plug into a chain's "Chat Model" slot.inputs: INodeParams[]declares the fields the UI renders. EachINodeParamshas atype(string,number,boolean,password,json,code,options,asyncOptions,datagrid,file,folder,tabs, …), plus options, defaults, conditionalshow/hiderules, andacceptVariableto allow{{$vars.*}}.loadMethodspopulateasyncOptionsdropdowns dynamically (e.g. fetch a provider's model list at edit time).vectorStoreMethodsare implemented by vector-store nodes to support upsert/search/delete.init()builds the underlying object (e.g. a LangChain chat model);run()executes it. Most "instance" nodes implementinit()and return a LangChain/LlamaIndex object that downstream nodes consume.credentialreferences one or moreINodeCredentialdefinitions; the resolved (decrypted) secret is passed inoptionsat runtime.
10.2 Anatomy of a typical node
class MyChatModel_ChatModels implements INode {
label = 'My Chat Model'
name = 'myChatModel'
version = 1.0
type = 'MyChatModel'
icon = 'mymodel.svg'
category = 'Chat Models'
baseClasses = ['MyChatModel', 'BaseChatModel', 'BaseLanguageModel']
credential: INodeParams = { label: 'Connect Credential', name: 'credential', type: 'credential', credentialNames: ['myApi'] }
inputs: INodeParams[] = [
{ label: 'Model Name', name: 'modelName', type: 'string', default: 'my-default' },
{ label: 'Temperature', name: 'temperature', type: 'number', default: 0.7, optional: true }
]
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
const apiKey = getCredentialParam('myApiKey', await getCredentialData(nodeData.credential, options), nodeData)
return new ProviderChatModel({ apiKey, model: nodeData.inputs?.modelName, temperature: nodeData.inputs?.temperature })
}
}
module.exports = { nodeClass: MyChatModel_ChatModels }
A node usually instantiates a real LangChain/LlamaIndex class — document the node's params and which class it wraps, not the library internals.
10.3 Credentials as nodes
Credentials are declared the same way (INodeCredential with inputs: INodeParams[]) and live alongside nodes in packages/components/credentials. They appear in the Connect Credential dropdown for any node that lists them in credentialNames.
10.4 Building & contributing
pnpm install
pnpm build # turbo build across all packages
pnpm dev # watch mode; UI on :8080, server on :3000
pnpm test # jest across packages
pnpm lint # eslint
Use migration:create (root) and the per-dialect typeorm:migration-* scripts (server package) when changing the schema. The repo uses changesets for versioning and husky + lint-staged for pre-commit checks. See CONTRIBUTING.md.
11. Code quality & conventions
- Language/build: TypeScript 5.4, Turborepo task graph, pnpm workspaces, Vite (UI + embeddable packages), gulp (asset copy for server/components), oclif (CLI).
- Style: Prettier (4-space, single quotes, no semicolons, width 140) + ESLint (TS, React, a11y, unused-imports). Enforced via husky/lint-staged.
- Testing: Jest unit tests (note the
*.test.tsfiles alongside controllers/services/nodes) + Cypress E2E inpackages/server/cypress. Coverage is modest —confidence_gapsflagged thin test coverage; treat broad refactors with care. - Patterns: Singleton "pools/managers" initialized at boot (NodesPool, CachePool, QueueManager, RateLimiterManager, IdentityManager); dependency-injection-free, module-singleton style. Clear MVC split in
server(routes/→controllers/→services/). - Error handling: centralized
errorHandlerMiddleware;InternalFlowiseErrorcarries HTTP status codes (http-status-codes). A deliberateuncaughtException/unhandledRejectioncatch-all keeps the process alive (flagged with aTODOto surface proper UI errors).
12. Potential improvements & tech debt
Observed from the source (candidates, not prescriptions):
- Process-level error swallowing.
BaseCommand.initregisters globaluncaughtException/unhandledRejectionhandlers that only log — the in-codeTODOnotes this should be replaced with structured error propagation to the UI. WORKER_CONCURRENCYdefault of100000is effectively "unbounded"; operators should set a realistic value to avoid resource exhaustion under load.- Node-version drift. README says Node
>= 20;engines.nodeis^24and the Docker image isnode:24-alpine. Pin a single supported version to avoid native-module build surprises (faiss-node,sqlite3are inonlyBuiltDependencies). - Test coverage is thin relative to surface area (the briefing flagged low coverage); the auto-
runMigrations({ transaction: 'each' })on every boot makes a migration test harness valuable before releases. - Custom-code sandbox depends on
vm2(pinned3.11.2);vm2is historically a source of sandbox-escape CVEs. Keep dependency allowlists tight and monitor advisories. - Pending hardening tracked in issues: MCP pre-execution trust hook (#6433), agent-memory poisoning defense (#6413), and the critical RCE advisory (#6444).
13. Troubleshooting (operations)
Error: Database migrations fail on boot
- Cause: Schema drift or a partially-applied migration after a downgrade.
- Solution: Restore from backup; never downgrade across a migration boundary. Check the dialect-specific migration set matches
DATABASE_TYPE.
Problem: Credentials decrypt to garbage after a restore
- Cause: Database restored without the matching encryption key.
- Solution: Restore the
SECRETKEY_PATHfile / AWS secret from the same backup point. Re-enter credentials only if the key is truly lost.
Problem: Predictions hang or pile up (queue mode)
- Cause: No workers running, Redis unreachable, or
WORKER_CONCURRENCYmis-set. - Solution: Confirm at least one
flowise workeris up and connected to the same Redis; inspect Bull-Board (ENABLE_BULLMQ_DASHBOARD); checkREDIS_*.
Error: Access to this host is denied by policy.
- Cause: SSRF protection blocked an outbound request from a node.
- Solution: Intended for internal/blocked hosts. If legitimate, narrow
HTTP_DENY_LIST; never disableHTTP_SECURITY_CHECKin production.
Problem: Behind a load balancer, cookies/HTTPS misbehave
- Cause: Proxy headers not trusted.
- Solution: Set
TRUST_PROXY,NUMBER_OF_PROXIES, andSECURE_COOKIES=true; terminate TLS at the proxy.
Problem: Web scraper / PDF loaders fail in Docker
- Cause: Missing/looked-up Chromium path.
- Solution: The official image bundles Chromium at
/usr/bin/chromium-browser; for custom images setPUPPETEER_EXECUTABLE_FILE_PATH/PLAYWRIGHT_EXECUTABLE_FILE_PATH.
Problem: Out-of-memory during build
- Cause: Monorepo build is memory-hungry.
- Solution:
NODE_OPTIONS=--max-old-space-size=4096(image already uses 8192).
14. Quick reference
14.1 CLI
| Command | Purpose |
|---|---|
flowise start |
Run the web/all-in-one server. |
flowise worker |
Run a queue-mode execution worker. |
flowise user |
User administration. |
flowise <cmd> --VAR=value |
Override any config variable as a flag. |
14.2 Critical production env vars
| Variable | Set to |
|---|---|
DATABASE_TYPE |
postgres |
STORAGE_TYPE |
s3 / gcs / azure |
SECRETKEY_STORAGE_TYPE |
aws (or inject FLOWISE_SECRETKEY_OVERWRITE) |
MODE |
queue (for scale) + REDIS_* |
JWT_*, EXPRESS_SESSION_SECRET, TOKEN_HASH_SECRET |
strong 32-byte secrets |
SECURE_COOKIES, TRUST_PROXY |
true / your proxy config |
HTTP_SECURITY_CHECK, PATH_TRAVERSAL_SAFETY |
true |
ALLOW_BUILTIN_DEP |
false |
ENABLE_METRICS |
true |
14.3 Key source locations
| Concern | Path |
|---|---|
| Server entry / boot | packages/server/src/index.ts |
| CLI commands & flags | packages/server/src/commands/{base,start,worker,user}.ts |
| API router composition | packages/server/src/routes/index.ts |
| Node SDK contract | packages/components/src/Interface.ts |
| Integration nodes | packages/components/nodes/<category>/ |
| Data entities | packages/server/src/database/entities/ |
| Migrations (per dialect) | packages/server/src/database/migrations/ |
| Queue manager | packages/server/src/queue/ |
| Enterprise/auth | packages/server/src/enterprise/ |
| Config defaults | docker/.env.example, packages/server/.env.example |