{"record":{"id":"abbe41fbc8feb718","repo":"FlowiseAI/Flowise","slug":"environment-variable-key-is-not-allowed-perm","errorCode":null,"errorMessage":"Environment variable '${key}' is not allowed. Permitted: ${[...allowedEnvVars].join(', ') || '(none)'}","messagePattern":"Environment variable '(.+?)' is not allowed\\. Permitted: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/MCP/core.ts","lineNumber":301,"sourceCode":"        }\n    }\n}\n\n/**\n * Validates user-supplied env vars against the operator-controlled allow-list in\n * `CUSTOM_MCP_ALLOWED_ENV_VARS` (comma-separated names). Empty = none allowed.\n */\nexport const validateEnvironmentVariables = (env: Record<string, any>): void => {\n    const allowedEnvVars = new Set(\n        (process.env.CUSTOM_MCP_ALLOWED_ENV_VARS ?? '')\n            .split(',')\n            .map((s) => s.trim())\n            .filter(Boolean)\n    )\n\n    for (const [key, value] of Object.entries(env)) {\n        if (!allowedEnvVars.has(key)) {\n            throw new Error(`Environment variable '${key}' is not allowed. Permitted: ${[...allowedEnvVars].join(', ') || '(none)'}`)\n        }\n\n        if (typeof value === 'string' && value.includes('\\0')) {\n            throw new Error(`Environment variable '${key}' contains null byte`)\n        }\n    }\n}\n\n/**\n * Validates that command arguments don't contain flags that enable arbitrary code execution\n * This prevents attacks where whitelisted commands are used with dangerous flags\n * (e.g., \"npx -c malicious-command\" or \"python -c malicious-code\")\n * @param command The command to validate\n * @param args The arguments to validate\n */\nexport const validateCommandFlags = (command: string, args: string[]): void => {\n    // Define dangerous flags for each command that enable code execution\n    const dangerousFlagsByCommand: Record<string, string[]> = {","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/MCP/core.ts#L283-L319","documentation":"Thrown by validateEnvironmentVariables when an env key passed to the MCP server is not in the operator-controlled CUSTOM_MCP_ALLOWED_ENV_VARS allow-list. The allow-list is built by splitting that env var on commas; default empty means no user env vars are forwarded. The message echoes both the offending key and the current permitted set (or '(none)').","triggerScenarios":"validateEnvironmentVariables(env) called from validateMCPServerConfig when serverParams.env is present, and env contains a key not in CUSTOM_MCP_ALLOWED_ENV_VARS.","commonSituations":"Custom MCP node forwards API keys or config via serverParams.env but the operator never allow-listed those names; env var name typo; new deployment without the allow-list configured.","solutions":["Add the exact env var name(s) to CUSTOM_MCP_ALLOWED_ENV_VARS (comma-separated).","Remove env keys from serverParams.env that the MCP server does not actually need.","Restart the worker after editing the env file so the new allow-list is loaded."],"exampleFix":"# before\n# CUSTOM_MCP_ALLOWED_ENV_VARS=\n\n# after\nCUSTOM_MCP_ALLOWED_ENV_VARS=API_KEY,HOME,DEBUG","handlingStrategy":"validation","validationCode":"const allowed = new Set((process.env.CUSTOM_MCP_ALLOWED_ENV_VARS ?? '').split(',').map(s => s.trim()).filter(Boolean))\nconst offenders = Object.keys(env).filter(k => !allowed.has(k))\nif (offenders.length) {\n  throw new Error(`Env vars not allow-listed: ${offenders.join(', ')}. Add to CUSTOM_MCP_ALLOWED_ENV_VARS`)\n}","typeGuard":"const envKeysAllowed = (env: Record<string, any>): boolean => {\n  const allowed = new Set((process.env.CUSTOM_MCP_ALLOWED_ENV_VARS ?? '').split(',').map(s => s.trim()).filter(Boolean))\n  return Object.keys(env).every(k => allowed.has(k))\n}","tryCatchPattern":"try {\n  validateEnvironmentVariables(env)\n} catch (e) {\n  if (e.message.includes('is not allowed')) {\n    // add the named key to CUSTOM_MCP_ALLOWED_ENV_VARS or drop it from env\n  }\n  throw e\n}","preventionTips":["Maintain the allow-list as part of deployment config and review it on each release.","Forward only the env vars the MCP server truly needs.","Add a CI check that diffs requested env names against the allow-list."],"tags":["mcp","security","configuration","env","allow-list"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}