Security
Credential encryption, template sandboxing, and security practices.
Credential encryption
All credentials (API keys, OAuth2 tokens, connection strings) are encrypted at rest using AES-256-GCM. Each credential has a unique IV (initialization vector) and authentication tag.
Generate a key with npx flowlib-cli secret. See CLI Reference for details.
Template sandboxing
Template expressions ({{ }}) are evaluated in a QuickJS WASM sandbox — an isolated JavaScript runtime compiled to WebAssembly. This means:
- No access to Node.js APIs —
fs,process,child_process,requireare unavailable - No network access —
fetch,XMLHttpRequest, WebSocket are unavailable - No
eval()orFunction()— dynamic code generation is blocked - Memory-limited — the sandbox has constrained memory
- Time-limited — expressions that run too long are terminated
Template expressions are for data transformation only. Use HTTP Request or custom action nodes for I/O.
OAuth2 security
Token handling
- Access tokens and refresh tokens are encrypted before database storage
- OAuth2 client secrets are encrypted alongside tokens
- Tokens are automatically refreshed when expired (via
getDecryptedWithRefresh) - State parameter with CSRF protection during the OAuth2 flow
Provider validation
- OAuth2 providers are defined in a registry — only known providers are accepted
- Authorization URLs are validated against the provider definition
- Callback URLs are validated against the state parameter
API security
Input validation
All API inputs are validated with Zod schemas before processing. Invalid requests return structured error responses.
Error handling
Error responses never leak internal details (stack traces, database queries, file paths) in production. Errors are logged server-side with full context for debugging.
Plugin security
Hook guardrails
Plugin hooks can intercept requests and execution:
onRequest— can read/modify requests, or return earlyonAuthorize— can grant/deny accessbeforeNodeExecute— can modify params or skip execution
Plugins run in the same Node.js process as the core. Only install plugins you trust.
Schema isolation
Plugin database tables are verified at startup. Each plugin's requiredTables are checked for existence before the server accepts requests.
Best practices
- Always set
FLOWLIB_ENCRYPTION_KEYin production — without it, credentials cannot be encrypted - Use HTTPS in production — credential data transits between the frontend and backend
- Use the Authentication Plugin for shared instances — without it, the API is unauthenticated
- Review plugin code — plugins have full access to the core instance and database