Skip to content

Security

Security is a core design principle of Octipus. Every tool call, API request, and stored credential is protected by multiple layers of security.

Octipus is multi-user by default. Every HTTP and WebSocket request must carry either a real session token (cookie, after login) or a personal octi_… api token. All requests run against scoped repositories with per-user (and per-org) isolation.

Tunable behaviors (via the Settings API):

SettingDefaultBehavior
multiuser.enforcePermissionstrueDeny cross-tenant reads/writes; collapses to 404 to avoid UUID enumeration.
multiuser.orgWorkspacestruePer-org workspace scoping for repos and uploads.
multiuser.rlsEnabledfalsePostgres row-level security. Opt-in — requires a non-superuser app role.
multiuser.auditShadowtrueMirror permission decisions into the audit log.

Admins can use Act as (impersonation) on the Users page; the impersonation banner stays visible and every action is audit-logged with both the real and effective principal.

Octipus supports four authentication methods:

The primary interactive method. Users log in with credentials and receive a JWT token that authenticates subsequent requests.

  • Tokens are issued on login and validated by the auth guard middleware
  • Public paths (health checks, registration, login) bypass authentication
  • Sessions are persisted across reloads via SESSION_SECRET-signed cookies

For MCP servers, CLI tools, the browser extension, and the TUI. Mint them in Settings → API Tokens in the web UI; they’re stored hashed in the api_tokens table and scoped to the issuing user.

  • Format: octi_<random>; shown once on creation
  • Sent as Authorization: Bearer octi_… (HTTP) or api_key (WebSocket)
  • Revocable from the same Settings page; deletion is immediate
  • On startup the backend mints a special mcp-bootstrap token for the first active admin and writes it to ~/.octipus/mcp-token (mode 600) so MCP clients can connect without manual setup — see MCP

The MASTER_KEY is the vault encryption root, not an auth credential. HKDF derives per-user data-encryption keys from it; rotating it goes through scripts/rotate-vault-keys.ts.

  • It does not authenticate HTTP/WS clients — every request uses a session token or a personal octi_… api token
  • Rotating it makes existing vault entries unrecoverable, so treat it as permanent (see the master-key warning in Configuration Precedence)

Hardware-backed passwordless authentication using the WebAuthn standard.

  • Register a passkey from the Settings page
  • Authenticate with your device’s biometric sensor or security key
  • Supported by all modern browsers and operating systems

Time-based One-Time Password (TOTP) for an additional layer of security.

  • Set up via the Settings page with any authenticator app (Google Authenticator, Authy, etc.)
  • Required on login once enabled
  • Can be disabled through the API with proper authentication

The vault provides AES-256-GCM encrypted credential storage for sensitive data like API keys, tokens, and passwords. The vault and database are the source of truth for all secrets — do not store credentials in .env files.

  • Per-skill access control: Credentials can be scoped to specific skills
  • Per-agent access control: Credentials can be limited to specific agents
  • Rotation support: Credentials can be rotated via the API without updating dependent configurations
  • Template-based injection: Skills reference secrets using templates rather than raw values
OperationEndpointDescription
ListGET /api/vaultList all stored credentials
StorePOST /api/vaultStore a new credential
UpdatePATCH /api/vault/:idUpdate an existing credential
DeleteDELETE /api/vault/:idDelete a credential
RotatePOST /api/vault/:id/rotateRotate a credential’s value

Tool permissions use a pattern-matching rule engine (inspired by claw-code-parity). Rules are evaluated in order: deny → allow → ask.

Syntax: tool_id(matcher)

PatternMeaningExample
shell(*)Wildcard — any shell commandAllow all shell use
shell(git:*)Prefix — commands starting with “git”Allow git commands
shell(git status)Exact — only this commandAllow only git status

Default rules:

{
"allow": ["shell(git:*)", "shell(ls:*)", "filesystem(*)", "knowledge(*)", "websearch(*)"],
"deny": ["shell(rm -rf /:*)", "shell(dd if=/dev:*)", "shell(mkfs:*)"],
"ask": ["shell(sudo:*)", "shell(docker:*)", "shell(systemctl:*)"]
}

Configure via Settings API: PUT /api/settings/permissions.rules

Every tool action is governed by one of three permission levels:

LevelBehaviorExample
ALLOWExecutes immediatelyReading files, searching the web
ASKPauses for user approvalWriting files, running commands
DENYBlocked entirelyDestructive shell commands

When a user denies a permission prompt (or it times out), the agent is immediately stopped — it does not retry or try alternative approaches. The orchestrator returns control to the user with a friendly message referencing the original request.

Hooks with trigger type tool_pre or tool_post run before/after tool execution:

  • Pre-tool hooks can block execution (deny decision)
  • Post-tool hooks can log, notify, or trigger downstream actions
  • Match tools via triggerConfig.toolPattern (wildcard, prefix, exact)

Permissions can be further refined with conditions:

  • Path patterns: Allow/deny based on file paths (e.g., allow writes only in ./workspace/)
  • Command patterns: Allow/deny based on command strings
  • Time windows: Restrict operations to specific time ranges
  • Rate limits: Limit how frequently a tool can be called

The secret injector enables agents to use vault credentials without exposing raw values. Tool arguments can reference secrets using a template syntax:

{{secret:my-api-key}}

When a tool call contains this template, the runtime:

  1. Looks up the secret my-api-key in the vault
  2. Decrypts the value
  3. Substitutes it into the tool argument before execution

The raw secret value is never exposed to the LLM or included in conversation history.

All security-relevant events are logged to the audit_log table:

  • User authentication (login, logout, failed attempts)
  • Permission requests and decisions
  • Vault operations (create, update, delete, rotate)
  • Tool executions with approval status

Each audit entry includes the user, action, resource, and timestamp for full traceability.