Add environment variable control for trust proxy setting (#5226)

* feat: allow trust proxy setting to be configured via environment variable

* fix: restore HTTP_DENY_LIST in .env.example after merge conflict

* feat: add conditional handling for trust proxy

* feat: add trust proxy environment variable documentation

* feat: add trust proxy environment variable sample value

* fix: handle empty trust proxy string in docker environment

---------

Co-authored-by: Henry Heng <henryheng@flowiseai.com>
This commit is contained in:
Yau 2025-09-27 21:08:55 +08:00 committed by GitHub
parent e48f28d13d
commit b5da234ce7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 66 additions and 45 deletions

View File

@ -120,45 +120,46 @@ Flowise has 3 different modules in a single mono repository.
Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder. Read [more](https://docs.flowiseai.com/environment-variables) Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder. Read [more](https://docs.flowiseai.com/environment-variables)
| Variable | Description | Type | Default | | Variable | Description | Type | Default |
| ---------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
| PORT | The HTTP port Flowise runs on | Number | 3000 | | PORT | The HTTP port Flowise runs on | Number | 3000 |
| CORS_ORIGINS | The allowed origins for all cross-origin HTTP calls | String | | | CORS_ORIGINS | The allowed origins for all cross-origin HTTP calls | String | |
| IFRAME_ORIGINS | The allowed origins for iframe src embedding | String | | | IFRAME_ORIGINS | The allowed origins for iframe src embedding | String | |
| FLOWISE_FILE_SIZE_LIMIT | Upload File Size Limit | String | 50mb | | FLOWISE_FILE_SIZE_LIMIT | Upload File Size Limit | String | 50mb |
| DEBUG | Print logs from components | Boolean | | | DEBUG | Print logs from components | Boolean | |
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/logs` | | LOG_PATH | Location where log files are stored | String | `your-path/Flowise/logs` |
| LOG_LEVEL | Different levels of logs | Enum String: `error`, `info`, `verbose`, `debug` | `info` | | LOG_LEVEL | Different levels of logs | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
| LOG_JSON_SPACES | Spaces to beautify JSON logs | | 2 | | LOG_JSON_SPACES | Spaces to beautify JSON logs | | 2 |
| TOOL_FUNCTION_BUILTIN_DEP | NodeJS built-in modules to be used for Custom Tool or Function | String | | | TOOL_FUNCTION_BUILTIN_DEP | NodeJS built-in modules to be used for Custom Tool or Function | String | |
| TOOL_FUNCTION_EXTERNAL_DEP | External modules to be used for Custom Tool or Function | String | | | TOOL_FUNCTION_EXTERNAL_DEP | External modules to be used for Custom Tool or Function | String | |
| ALLOW_BUILTIN_DEP | Allow project dependencies to be used for Custom Tool or Function | Boolean | false | | ALLOW_BUILTIN_DEP | Allow project dependencies to be used for Custom Tool or Function | Boolean | false |
| DATABASE_TYPE | Type of database to store the flowise data | Enum String: `sqlite`, `mysql`, `postgres` | `sqlite` | | DATABASE_TYPE | Type of database to store the flowise data | Enum String: `sqlite`, `mysql`, `postgres` | `sqlite` |
| DATABASE_PATH | Location where database is saved (When DATABASE_TYPE is sqlite) | String | `your-home-dir/.flowise` | | DATABASE_PATH | Location where database is saved (When DATABASE_TYPE is sqlite) | String | `your-home-dir/.flowise` |
| DATABASE_HOST | Host URL or IP address (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_HOST | Host URL or IP address (When DATABASE_TYPE is not sqlite) | String | |
| DATABASE_PORT | Database port (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_PORT | Database port (When DATABASE_TYPE is not sqlite) | String | |
| DATABASE_USER | Database username (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_USER | Database username (When DATABASE_TYPE is not sqlite) | String | |
| DATABASE_PASSWORD | Database password (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_PASSWORD | Database password (When DATABASE_TYPE is not sqlite) | String | |
| DATABASE_NAME | Database name (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_NAME | Database name (When DATABASE_TYPE is not sqlite) | String | |
| DATABASE_SSL_KEY_BASE64 | Database SSL client cert in base64 (takes priority over DATABASE_SSL) | Boolean | false | | DATABASE_SSL_KEY_BASE64 | Database SSL client cert in base64 (takes priority over DATABASE_SSL) | Boolean | false |
| DATABASE_SSL | Database connection overssl (When DATABASE_TYPE is postgre) | Boolean | false | | DATABASE_SSL | Database connection overssl (When DATABASE_TYPE is postgre) | Boolean | false |
| SECRETKEY_PATH | Location where encryption key (used to encrypt/decrypt credentials) is saved | String | `your-path/Flowise/packages/server` | | SECRETKEY_PATH | Location where encryption key (used to encrypt/decrypt credentials) is saved | String | `your-path/Flowise/packages/server` |
| FLOWISE_SECRETKEY_OVERWRITE | Encryption key to be used instead of the key stored in SECRETKEY_PATH | String | | | FLOWISE_SECRETKEY_OVERWRITE | Encryption key to be used instead of the key stored in SECRETKEY_PATH | String | |
| MODEL_LIST_CONFIG_JSON | File path to load list of models from your local config file | String | `/your_model_list_config_file_path` | | MODEL_LIST_CONFIG_JSON | File path to load list of models from your local config file | String | `/your_model_list_config_file_path` |
| STORAGE_TYPE | Type of storage for uploaded files. default is `local` | Enum String: `s3`, `local`, `gcs` | `local` | | STORAGE_TYPE | Type of storage for uploaded files. default is `local` | Enum String: `s3`, `local`, `gcs` | `local` |
| BLOB_STORAGE_PATH | Local folder path where uploaded files are stored when `STORAGE_TYPE` is `local` | String | `your-home-dir/.flowise/storage` | | BLOB_STORAGE_PATH | Local folder path where uploaded files are stored when `STORAGE_TYPE` is `local` | String | `your-home-dir/.flowise/storage` |
| S3_STORAGE_BUCKET_NAME | Bucket name to hold the uploaded files when `STORAGE_TYPE` is `s3` | String | | | S3_STORAGE_BUCKET_NAME | Bucket name to hold the uploaded files when `STORAGE_TYPE` is `s3` | String | |
| S3_STORAGE_ACCESS_KEY_ID | AWS Access Key | String | | | S3_STORAGE_ACCESS_KEY_ID | AWS Access Key | String | |
| S3_STORAGE_SECRET_ACCESS_KEY | AWS Secret Key | String | | | S3_STORAGE_SECRET_ACCESS_KEY | AWS Secret Key | String | |
| S3_STORAGE_REGION | Region for S3 bucket | String | | | S3_STORAGE_REGION | Region for S3 bucket | String | |
| S3_ENDPOINT_URL | Custom Endpoint for S3 | String | | | S3_ENDPOINT_URL | Custom Endpoint for S3 | String | |
| S3_FORCE_PATH_STYLE | Set this to true to force the request to use path-style addressing | Boolean | false | | S3_FORCE_PATH_STYLE | Set this to true to force the request to use path-style addressing | Boolean | false |
| GOOGLE_CLOUD_STORAGE_PROJ_ID | The GCP project id for cloud storage & logging when `STORAGE_TYPE` is `gcs` | String | | | GOOGLE_CLOUD_STORAGE_PROJ_ID | The GCP project id for cloud storage & logging when `STORAGE_TYPE` is `gcs` | String | |
| GOOGLE_CLOUD_STORAGE_CREDENTIAL | The credential key file path when `STORAGE_TYPE` is `gcs` | String | | | GOOGLE_CLOUD_STORAGE_CREDENTIAL | The credential key file path when `STORAGE_TYPE` is `gcs` | String | |
| GOOGLE_CLOUD_STORAGE_BUCKET_NAME | Bucket name to hold the uploaded files when `STORAGE_TYPE` is `gcs` | String | | | GOOGLE_CLOUD_STORAGE_BUCKET_NAME | Bucket name to hold the uploaded files when `STORAGE_TYPE` is `gcs` | String | |
| GOOGLE_CLOUD_UNIFORM_BUCKET_ACCESS | Enable uniform bucket level access when `STORAGE_TYPE` is `gcs` | Boolean | true | | GOOGLE_CLOUD_UNIFORM_BUCKET_ACCESS | Enable uniform bucket level access when `STORAGE_TYPE` is `gcs` | Boolean | true |
| SHOW_COMMUNITY_NODES | Show nodes created by community | Boolean | | | SHOW_COMMUNITY_NODES | Show nodes created by community | Boolean | |
| DISABLED_NODES | Hide nodes from UI (comma separated list of node names) | String | | | DISABLED_NODES | Hide nodes from UI (comma separated list of node names) | String | |
| TRUST_PROXY | Configure proxy trust settings for proper IP detection. Values: 'true' (trust all), 'false' (disable), number (hop count), or Express proxy values (e.g., 'loopback', 'linklocal', 'uniquelocal', IP addresses). [Learn More](https://expressjs.com/en/guide/behind-proxies.html) | Boolean/String/Number | true |
You can also specify the env variables when using `npx`. For example: You can also specify the env variables when using `npx`. For example:

View File

@ -174,3 +174,4 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
# HTTP_DENY_LIST= # HTTP_DENY_LIST=
# CUSTOM_MCP_SECURITY_CHECK=true # CUSTOM_MCP_SECURITY_CHECK=true
# CUSTOM_MCP_PROTOCOL=sse #(stdio | sse) # CUSTOM_MCP_PROTOCOL=sse #(stdio | sse)
# TRUST_PROXY=true #(true | false | 1 | loopback| linklocal | uniquelocal | IP addresses | loopback, IP addresses)

View File

@ -140,10 +140,11 @@ services:
- REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE} - REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE}
- ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD} - ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD}
# SECURITY # SECURITY
- CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK} - CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK}
- CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL} - CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL}
- HTTP_DENY_LIST=${HTTP_DENY_LIST} - HTTP_DENY_LIST=${HTTP_DENY_LIST}
- TRUST_PROXY=${TRUST_PROXY}
healthcheck: healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:${PORT:-3000}/api/v1/ping'] test: ['CMD', 'curl', '-f', 'http://localhost:${PORT:-3000}/api/v1/ping']
interval: 10s interval: 10s
@ -282,10 +283,11 @@ services:
- REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE} - REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE}
- ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD} - ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD}
# SECURITY # SECURITY
- CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK} - CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK}
- CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL} - CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL}
- HTTP_DENY_LIST=${HTTP_DENY_LIST} - HTTP_DENY_LIST=${HTTP_DENY_LIST}
- TRUST_PROXY=${TRUST_PROXY}
healthcheck: healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:${WORKER_PORT:-5566}/healthz'] test: ['CMD', 'curl', '-f', 'http://localhost:${WORKER_PORT:-5566}/healthz']
interval: 10s interval: 10s

View File

@ -125,10 +125,11 @@ services:
- REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE} - REDIS_KEEP_ALIVE=${REDIS_KEEP_ALIVE}
- ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD} - ENABLE_BULLMQ_DASHBOARD=${ENABLE_BULLMQ_DASHBOARD}
# SECURITY # SECURITY
- CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK} - CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK}
- CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL} - CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL}
- HTTP_DENY_LIST=${HTTP_DENY_LIST} - HTTP_DENY_LIST=${HTTP_DENY_LIST}
- TRUST_PROXY=${TRUST_PROXY}
ports: ports:
- '${PORT}:${PORT}' - '${PORT}:${PORT}'
healthcheck: healthcheck:

View File

@ -174,3 +174,4 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
# HTTP_DENY_LIST= # HTTP_DENY_LIST=
# CUSTOM_MCP_SECURITY_CHECK=true # CUSTOM_MCP_SECURITY_CHECK=true
# CUSTOM_MCP_PROTOCOL=sse #(stdio | sse) # CUSTOM_MCP_PROTOCOL=sse #(stdio | sse)
# TRUST_PROXY=true #(true | false | 1 | loopback| linklocal | uniquelocal | IP addresses | loopback, IP addresses)

View File

@ -129,7 +129,7 @@ services:
- CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK} - CUSTOM_MCP_SECURITY_CHECK=${CUSTOM_MCP_SECURITY_CHECK}
- CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL} - CUSTOM_MCP_PROTOCOL=${CUSTOM_MCP_PROTOCOL}
- HTTP_DENY_LIST=${HTTP_DENY_LIST} - HTTP_DENY_LIST=${HTTP_DENY_LIST}
- TRUST_PROXY=${TRUST_PROXY}
ports: ports:
- '${WORKER_PORT}:${WORKER_PORT}' - '${WORKER_PORT}:${WORKER_PORT}'
healthcheck: healthcheck:

View File

@ -174,6 +174,7 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
# HTTP_DENY_LIST= # HTTP_DENY_LIST=
# CUSTOM_MCP_SECURITY_CHECK=true # CUSTOM_MCP_SECURITY_CHECK=true
# CUSTOM_MCP_PROTOCOL=sse #(stdio | sse) # CUSTOM_MCP_PROTOCOL=sse #(stdio | sse)
# TRUST_PROXY=true #(true | false | 1 | loopback| linklocal | uniquelocal | IP addresses | loopback, IP addresses)
############################################################################################################ ############################################################################################################

View File

@ -77,7 +77,8 @@ export abstract class BaseCommand extends Command {
ENABLE_BULLMQ_DASHBOARD: Flags.string(), ENABLE_BULLMQ_DASHBOARD: Flags.string(),
CUSTOM_MCP_SECURITY_CHECK: Flags.string(), CUSTOM_MCP_SECURITY_CHECK: Flags.string(),
CUSTOM_MCP_PROTOCOL: Flags.string(), CUSTOM_MCP_PROTOCOL: Flags.string(),
HTTP_DENY_LIST: Flags.string() HTTP_DENY_LIST: Flags.string(),
TRUST_PROXY: Flags.string()
} }
protected async stopProcess() { protected async stopProcess() {
@ -210,5 +211,6 @@ export abstract class BaseCommand extends Command {
if (flags.CUSTOM_MCP_SECURITY_CHECK) process.env.CUSTOM_MCP_SECURITY_CHECK = flags.CUSTOM_MCP_SECURITY_CHECK if (flags.CUSTOM_MCP_SECURITY_CHECK) process.env.CUSTOM_MCP_SECURITY_CHECK = flags.CUSTOM_MCP_SECURITY_CHECK
if (flags.CUSTOM_MCP_PROTOCOL) process.env.CUSTOM_MCP_PROTOCOL = flags.CUSTOM_MCP_PROTOCOL if (flags.CUSTOM_MCP_PROTOCOL) process.env.CUSTOM_MCP_PROTOCOL = flags.CUSTOM_MCP_PROTOCOL
if (flags.HTTP_DENY_LIST) process.env.HTTP_DENY_LIST = flags.HTTP_DENY_LIST if (flags.HTTP_DENY_LIST) process.env.HTTP_DENY_LIST = flags.HTTP_DENY_LIST
if (flags.TRUST_PROXY) process.env.TRUST_PROXY = flags.TRUST_PROXY
} }
} }

View File

@ -163,7 +163,19 @@ export class App {
this.app.use(express.urlencoded({ limit: flowise_file_size_limit, extended: true })) this.app.use(express.urlencoded({ limit: flowise_file_size_limit, extended: true }))
// Enhanced trust proxy settings for load balancer // Enhanced trust proxy settings for load balancer
this.app.set('trust proxy', true) // Trust all proxies let trustProxy: string | boolean | number | undefined = process.env.TRUST_PROXY
if (typeof trustProxy === 'undefined' || trustProxy.trim() === '' || trustProxy === 'true') {
// Default to trust all proxies
trustProxy = true
} else if (trustProxy === 'false') {
// Disable trust proxy
trustProxy = false
} else if (!isNaN(Number(trustProxy))) {
// Number: Trust specific number of proxies
trustProxy = Number(trustProxy)
}
this.app.set('trust proxy', trustProxy)
// Allow access from specified domains // Allow access from specified domains
this.app.use(cors(getCorsOptions())) this.app.use(cors(getCorsOptions()))