Security model
Project isolation, secret handling, bounded execution, explicit tool permissions, and outbound network rules.
Tenant isolation
Every routine, connection, run, API key, and webhook lookup includes the active project identifier. The API does not trust a project identifier supplied by the caller: it resolves one from the API key, or from a verified session's membership.
A resource belonging to another project returns 404, never 403 — the API
does not confirm the existence of something you cannot see.
Secrets
- API keys are hashed with SHA-256 and shown once, at creation.
- MCP connection headers, OAuth access tokens, and webhook signing secrets are
encrypted at rest with
ENCRYPTION_KEY. - Encrypted values are never returned by the API, including to their owner.
- Error messages and execution records are redacted for common secret shapes.
- Secrets belong in service environment variables, never in tracked files.
The model never receives a credential. Connection headers are resolved server-side at tool-call time and attached to the outbound request, outside the model's context.
Model and tool execution
Model inference goes through LLMGateway. Production refuses to start without gateway credentials, and refuses to start at all with demo mode enabled.
Execution is bounded on three axes:
| Bound | Value |
|---|---|
| Model steps per run | 1–25, set per routine |
| Wall-clock per run | 30–1200 seconds, set per routine |
| Authenticated API requests | Rate limited per credential in a 60s window |
| Request body size | 1 MB on /v1 |
MCP capabilities are disabled by default, and automatic external tool execution always requires an explicit, tool-specific confirmation. See Tool permissions.
Outbound network rules
Outbound MCP and webhook requests:
- reject credentials embedded in URLs;
- do not follow redirects;
- refuse loopback, link-local, and private or special-use addresses in production; and
- pin the validated DNS answers to the connection, closing the window where a hostname resolves safely during validation and to an internal address during use.
Webhook deliveries additionally time out after 10 seconds.
Webhook authenticity
Payloads are signed with HMAC-SHA256 over `${timestamp}.${rawBody}` using
a per-routine secret. Consumers should validate the timestamp against a replay
window, compute the signature over the unmodified body, and compare in constant
time. See Receive run webhooks.
Your responsibilities
Work on Repeat bounds what a routine can do. What it should do is yours: