# Security (/docs/security)





## Credential encryption [#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](/docs/reference/cli) for details.

## Template sandboxing [#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`, `require` are unavailable
* **No network access** — `fetch`, `XMLHttpRequest`, WebSocket are unavailable
* **No `eval()` or `Function()`** — 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 [#oauth2-security]

### Token handling [#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 [#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 [#api-security]

### Input validation [#input-validation]

All API inputs are validated with Zod schemas before processing. Invalid requests return structured error responses.

### Error handling [#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 [#plugin-security]

### Hook guardrails [#hook-guardrails]

Plugin hooks can intercept requests and execution:

* `onRequest` — can read/modify requests, or return early
* `onAuthorize` — can grant/deny access
* `beforeNodeExecute` — can modify params or skip execution

Plugins run in the same Node.js process as the core. Only install plugins you trust.

### Schema isolation [#schema-isolation]

Plugin database tables are verified at startup. Each plugin's `requiredTables` are checked for existence before the server accepts requests.

## Best practices [#best-practices]

* **Always set `FLOWLIB_ENCRYPTION_KEY`** in 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
