Security
Octipus implements authentication, scoped data access, encrypted secrets, tool permissions, and audit records. These are controls with deployment-specific limits, not a certification of complete isolation or prompt-injection resistance.
Authentication and users
Section titled “Authentication and users”Protected backend routes accept an HttpOnly session cookie or a personal
octi_… Bearer token. POST /api/auth/login sets the browser cookie;
POST /api/auth/login-mobile returns a token and expiry for native clients.
Passkeys and TOTP are also supported. Public health/authentication routes and
signed webhook/SSO endpoints have their own requirements.
Create personal tokens in the API Tokens UI or POST /api/auth/api-tokens.
Tokens are shown once, stored hashed, and can be revoked. An empty scope list
means full access; restrict automation tokens to required routes. MASTER_KEY
is not an HTTP or WebSocket credential.
User/workspace scoping, organization controls, and optional PostgreSQL RLS form part of the backend access model. A scope setting is not evidence that every external integration shares the same isolation boundary.
Vault and key rotation
Section titled “Vault and key rotation”The vault encrypts credentials with AES-256-GCM and scope-derived keys. Runtime integration secrets belong in the vault; bootstrap encryption/session keys stay in the deployment environment. Secret references reduce direct model exposure, but external tools and their output still need appropriate controls.
Do not simply replace MASTER_KEY: existing ciphertext would become unreadable.
The maintenance script is scripts/rotate-master-key.ts; it re-encrypts active
vault rows using OLD_MASTER_KEY and NEW_MASTER_KEY. Back up first, stop
writers, inspect per-row failures, and change the deployment key only after
successful rotation. Its dry-run counts candidates without validating every
decryption, and partial failures currently do not produce a nonzero exit.
See Configuration precedence.
Execution permissions
Section titled “Execution permissions”| Level | Behavior |
|---|---|
| ALLOW | Executes if applicable scope and other checks pass |
| ASK | Prompts on an attended session; blocks when unattended |
| DENY | Refuses the action |
Attended descendants inherit the session approval surface. REST-driven tool calls, hooks, and other unattended work do not automatically approve ASK. Stored DENY wins over broad allow rules. Middleware rechecks after argument hooks; an approval receipt is single-use and bound to caller, action, and arguments.
Use PUT /api/tools/permissions with toolId, action, level, and optionally
scope. A scope needs a future expiresAt and at least one of sessionId,
workspaceId, pathPattern, or commandPattern. Conditions combine; unavailable
or mismatched evidence blocks access. A scoped ALLOW cannot overwrite an existing
DENY. Removing an override restores its manifest default; set ASK explicitly to
require review when that default is ALLOW.
Direct tool execution returns HTTP 409 with approval_required for blocked
ASK. MCP outbound permissions use tool ID mcp and action
<serverId>.<remoteToolName>; old mcp:<serverId> overrides need review.
Boundaries and evidence
Section titled “Boundaries and evidence”Argument patterns are authorization checks, not a filesystem or shell sandbox. CLI workers and external MCP servers execute code outside the built-in tool middleware’s full visibility. Configure process isolation and trust accordingly.
Audit logs and swarm receipts record observed activity. Missing evidence must not be interpreted as proof that nothing happened. Prompt guards and security preambles mitigate some injection attempts but do not replace permissions. Red-team CI checks case generation in dry-run mode; it is not a live-model adversarial performance guarantee.