Skip to content

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.

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.

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.

LevelBehavior
ALLOWExecutes if applicable scope and other checks pass
ASKPrompts on an attended session; blocks when unattended
DENYRefuses 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.

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.