# Flowise Admin Guide

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 `INode` and `NodesPool`, 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

```text
                         ┌──────────────────────────────────────────┐
   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:

1. **DataSource initialize** — connect via TypeORM.
2. **Run migrations** — each in its own transaction; schema is auto-migrated on every boot.
3. **IdentityManager** — auth/enterprise identity (users, orgs, workspaces, plan features).
4. **NodesPool** — scan `flowise-components` and load every node class into memory.
5. **AbortControllerPool** — registry for cancelling in-flight predictions.
6. **Encryption key** — load/generate the key used to encrypt stored credentials.
7. **Auth secrets** — resolve JWT/session/hash secrets (env → AWS Secrets Manager → filesystem).
8. **Rate limiters** — built per-chatflow from saved rate-limit config.
9. **CachePool** + **UsageCacheManager** — response/usage caches.
10. **QueueManager** — only when `MODE=queue`; wires BullMQ queues and the Bull-Board dashboard.
11. **Metrics provider** — Prometheus or OpenTelemetry, if `ENABLE_METRICS=true`.
12. **SSEStreamer** — server-sent-events channel for streaming.
13. **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:

1. The chatflow's saved JSON graph is loaded.
2. Nodes are **instantiated** from `NodesPool` and topologically resolved.
3. Each node's `init()`/`run()` is invoked with resolved inputs and an options bag (session, credentials, callbacks).
4. Streaming output is pushed through `SSEStreamer`; the run is cancellable via `AbortControllerPool`.
5. 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=queue` is 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=aws` or inject `FLOWISE_SECRETKEY_OVERWRITE` from 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)

```bash
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 `.env` into the container.
- Persists `~/.flowise` via a volume (`~/.flowise:/root/.flowise`).
- Defines a **healthcheck** hitting `/api/v1/ping`.

> [!WARNING]
> The default volume mounts the host's `~/.flowise`. For production, point `DATABASE_*` at an external PostgreSQL and `STORAGE_TYPE` at 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 set `SECURE_COOKIES=true`, `TRUST_PROXY`, and `NUMBER_OF_PROXIES`.

### 7.2 Production checklist

- [ ] `DATABASE_TYPE=postgres` with managed PostgreSQL (and `DATABASE_SSL=true`).
- [ ] `STORAGE_TYPE=s3|gcs|azure` for durable file storage.
- [ ] `SECRETKEY_STORAGE_TYPE=aws` or injected `FLOWISE_SECRETKEY_OVERWRITE`.
- [ ] Strong, externally-managed `JWT_*`, `EXPRESS_SESSION_SECRET`, `TOKEN_HASH_SECRET` (`openssl rand -hex 32`).
- [ ] HTTPS at the proxy; `SECURE_COOKIES=true`; `CORS_ORIGINS` and `IFRAME_ORIGINS` locked to known origins.
- [ ] `HTTP_SECURITY_CHECK=true`, sensible `HTTP_DENY_LIST` (block cloud metadata IPs, internal ranges).
- [ ] Custom-code deps restricted (`ALLOW_BUILTIN_DEP=false`, tight `TOOL_FUNCTION_*_DEP`).
- [ ] MCP: keep `CUSTOM_MCP_PROTOCOL=sse`; only `stdio` for fully trusted operators.
- [ ] Backups for the database **and** the encryption key.
- [ ] `ENABLE_METRICS=true` wired to Prometheus/OTel; log shipping configured.

### 7.3 Scaling with queue mode

For high concurrency, run the **web** tier and **worker** tier separately:

```bash
# 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), and `flowise 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 (`ApiKey` entity), validated by `validateAPIKey` middleware; 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](https://github.com/FlowiseAI/Flowise/issues/6444)** — request for CVE assignment for **GHSA-jg8m-mc94-2g3x (Critical RCE)**. Track the advisory and stay on the latest release.
- **[#6433](https://github.com/FlowiseAI/Flowise/issues/6433)** — proposed pre-execution trust-verification hook for MCP tool calls.
- **[#6413](https://github.com/FlowiseAI/Flowise/issues/6413)** — agent-memory poisoning hardening (OWASP ASI06).

> [!CAUTION]
> Treat any Flowise instance that allows untrusted users to author Custom Tools/Functions or Custom MCP `stdio` servers 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

1. Read the release notes for breaking changes/migrations.
2. Back up DB + key.
3. Pull the new image / `pnpm install && pnpm build`.
4. Restart — migrations run automatically.
5. 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**:

```typescript
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:

- **`baseClasses`** drive **anchor compatibility** — a node whose `baseClasses` includes `BaseChatModel` can connect to any input that accepts a `BaseChatModel`. 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. Each `INodeParams` has a `type` (`string`, `number`, `boolean`, `password`, `json`, `code`, `options`, `asyncOptions`, `datagrid`, `file`, `folder`, `tabs`, …), plus options, defaults, conditional `show`/`hide` rules, and `acceptVariable` to allow `{{$vars.*}}`.
- **`loadMethods`** populate `asyncOptions` dropdowns dynamically (e.g. fetch a provider's model list at edit time).
- **`vectorStoreMethods`** are 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 implement `init()` and return a LangChain/LlamaIndex object that downstream nodes consume.
- **`credential`** references one or more `INodeCredential` definitions; the resolved (decrypted) secret is passed in `options` at runtime.

### 10.2 Anatomy of a typical node

```typescript
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

```bash
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.ts` files alongside controllers/services/nodes) + Cypress E2E in `packages/server/cypress`. Coverage is modest — `confidence_gaps` flagged 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`; `InternalFlowiseError` carries HTTP status codes (`http-status-codes`). A deliberate `uncaughtException`/`unhandledRejection` catch-all keeps the process alive (flagged with a `TODO` to surface proper UI errors).

---

## 12. Potential improvements & tech debt

Observed from the source (candidates, not prescriptions):

- **Process-level error swallowing.** `BaseCommand.init` registers global `uncaughtException`/`unhandledRejection` handlers that only log — the in-code `TODO` notes this should be replaced with structured error propagation to the UI.
- **`WORKER_CONCURRENCY` default of `100000`** is effectively "unbounded"; operators should set a realistic value to avoid resource exhaustion under load.
- **Node-version drift.** README says Node `>= 20`; `engines.node` is `^24` and the Docker image is `node:24-alpine`. Pin a single supported version to avoid native-module build surprises (`faiss-node`, `sqlite3` are in `onlyBuiltDependencies`).
- **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` (pinned `3.11.2`); `vm2` is 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](https://github.com/FlowiseAI/Flowise/issues/6433)), agent-memory poisoning defense ([#6413](https://github.com/FlowiseAI/Flowise/issues/6413)), and the critical RCE advisory ([#6444](https://github.com/FlowiseAI/Flowise/issues/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_PATH` file / 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_CONCURRENCY` mis-set.
- **Solution:** Confirm at least one `flowise worker` is up and connected to the same Redis; inspect Bull-Board (`ENABLE_BULLMQ_DASHBOARD`); check `REDIS_*`.

### 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 disable `HTTP_SECURITY_CHECK` in production.

### Problem: Behind a load balancer, cookies/HTTPS misbehave
- **Cause:** Proxy headers not trusted.
- **Solution:** Set `TRUST_PROXY`, `NUMBER_OF_PROXIES`, and `SECURE_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 set `PUPPETEER_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` |

---

_Generated June 2026 from FlowiseAI/Flowise at a4c4e49. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
