Knockout Security

How your code, credentials, and sessions stay yours

Knockout sessions touch your real codebase, your real API keys, and chunks of every file the agent reads. None of that should sit unprotected on a server. The platform encrypts it with a key only you derive, refuses every plaintext write at both the application and database layer, and never holds your vault password.

Recent hardening

How your code is protected

1You set a vault password at signup (never stored on server, never recoverable)
2scrypt derives a 256-bit key from the password and a random 32-byte salt
3Session messages, API keys, and personal data are encrypted with AES-256-GCM (authenticated encryption) before any row lands in the database
4Vault key is cached in vault_sessions, wrapped with the server key, with a 1 h rolling idle TTL extended only by real cryptographic use
5Workers fetch a short-lived HMAC-signed lease over mTLS — the key never crosses a process boundary in plaintext

What's encrypted

DataIn the vaultNotes
Session prompts & responses EncryptedEvery Knockout turn, system prompts, generated code
LLM provider API keys EncryptedOpenAI, Anthropic, Google, Groq, etc.
Signup IP EncryptedGDPR personal data
Last-login IP EncryptedGDPR personal data
Tool call outputs in session history EncryptedCaptured inside the message stream
File paths & names quoted in prompts EncryptedSit inside encrypted message bodies
Account email & username PlaintextRequired plaintext for login + uniqueness
Account password hash Plaintextscrypt-hashed, never reversible
Wallet balance & subscription status PlaintextRequired for billing flows

Architecture

Zero-Knowledge Design

Your vault password is never stored on the server, not even as a hash. We store only a random salt and an encrypted verifier (a known plaintext encrypted with your derived key). The server can prove your password is correct but cannot recover it or derive the key without it.

Session Lifecycle

When you unlock the vault, the derived key is wrapped with the server master key and cached with a 1-hour rolling idle TTL. Extended only by real cryptographic use — not by status polls or forgotten tabs. An idle session dies and re-prompts; an actively used session can live indefinitely.

Worker Lease Handoff

Knockout workers run on separate boxes from the web tier. They fetch a per-session, HMAC-signed vault lease over mTLS, hold the key in process memory only for the duration of the session, and never persist it. Each session gets its own lease scope — cross-session reuse is rejected.

Database-Enforced Invariant

A PostgreSQL CHECK constraint on ko_sessions requires is_encrypted=true OR legacy_plaintext=true. Even if a code path tried to write plaintext, the database would refuse. Defence in depth: the application refuses too.

Vault session lifecycle

unlock

verifier check

use

decrypt → +1 h

1 h idle

no crypto → expire

Status reads (isVaultUnlocked) are passive — they do NOT extend the TTL. Only real work does.

CLI hardening

Scoped API Tokens

Each ko token has fine-grained scopes — session:create, sync:push, config:write. Tokens are stored as SHA-256 hashes server-side; the full token is shown once at creation and cannot be retrieved. Revoke any token instantly from Settings.

Vault Password in OS Keychain

The CLI stores the vault password in your OS keychain — macOS Keychain, Linux libsecret, Windows Credential Manager — not in a plaintext config file. Existing plaintext passwords get migrated to the keychain on first run.

Browser-Based OAuth Login

ko auth login opens a secure browser flow. You authenticate on the platform; the CLI receives a scoped token automatically. No passwords are typed into the terminal. CSRF state validation and reCAPTCHA protect the handshake.

Signed Binary Updates

Self-updates are verified with Ed25519 digital signatures. The signing public key is embedded in the binary at build time. Downloaded updates that don't match get rejected — protecting against MITM and tampered binaries on the update path.

Filesystem & tool safety

Working-Directory Boundary

The CLI's file Read/Write/Edit tools are restricted to your project's working directory. Symlink escapes are detected and blocked. Access to ~/.ssh, ~/.aws, ~/.gnupg, and other sensitive paths is denied by a hardcoded denylist.

Command Injection Prevention

The CLI detects and blocks compound shell commands (pipes, semicolons, backticks, subshells) in tool calls. Dangerous commands require explicit user approval. Server-side admin commands use execFile (no shell) with strict input validation.

Zero-Knowledge Snapshots

Code pushed via ko sync push is encrypted on your machine before upload, using AES-256-GCM with a key derived from your vault password (scrypt). The platform stores only ciphertext.

Secure Local WebSocket

The CLI's Web UI WebSocket binds to 127.0.0.1 only, validates Origin headers, and requires a one-time cryptographic nonce. Malicious websites and local processes cannot connect without it.

Platform API hardening

Tiered Rate Limiting

Every Knockout API endpoint is rate-limited — 5/min on auth routes, 20/min on resource creation, 30/min on mutations, 60/min on reads. In-memory sliding window per IP, blocks brute-force and abuse.

CSRF Protection

Every mutating browser request is validated against Origin and Referer headers. CLI requests use Bearer tokens and are stateless, so they bypass CSRF cleanly without losing protection on the browser path.

Strict Input Validation

All inputs validated with length, type, enum, and regex constraints. Hostnames, SSH usernames, and ports use allowlist patterns. No unbounded input reaches the database.

Security Headers

HSTS (1 year), X-Frame-Options DENY, strict CSP, X-Content-Type nosniff, strict Referrer-Policy enforced on every response. frame-ancestors none prevents clickjacking.

Backup & recovery

Doubly-Encrypted Backups

Daily PostgreSQL dump → AES-256-CBC + pbkdf2 wrapper (passphrase only on the source box) → OVH S3. Two keys required to read: the backup passphrase plus every affected user's vault password. 30-day retention.

Restore-Tested

The restore script downloads, decrypts, and lands the dump into a separate fightclub_restore database — never the live DB without an explicit operator promotion. Row counts verified to match live during deploy.

No Password Recovery

By design, the vault password cannot be recovered. If you forget it, your encrypted sessions, API keys, and personal data are permanently unreachable. You can reset the vault — which deletes everything encrypted and lets you start fresh — but the old data is gone forever. This is the trade-off for true zero-knowledge security: nobody, not even us, can read your encrypted data without your password.

What you should do

1

Save your vault password somewhere durable

Password manager, paper, anywhere that isn't this machine. If you forget it, every encrypted thing on the platform is gone — we cannot help you recover it.

2

Unlock the vault when you sit down to work

Click Unlock vault on the dashboard. The session rolls forward every time you actually use it. Forgotten tabs won't keep it alive — only real work does.

3

Lock the vault on shared computers before walking away

On a work laptop, university PC, or anywhere someone else might use the machine, explicitly lock + sign out. The login session itself auto-expires after 1 hour idle.

4

Clean up any ⚠ unencrypted sessions on your sessions list

Old rows from before the encryption rollout auto-upgrade the next time you open them with the vault unlocked, or you can Delete them to redact entirely.

Technical specifications

Encryption Algorithm
AES-256-GCM
IV Length
12 bytes (random per operation)
Auth Tag
16 bytes (tamper detection)
Key Derivation
scrypt (N=16384, r=8, p=1)
Vault Salt
32 bytes (random per user)
Vault Key Size
256 bits
Vault Session TTL
1 h rolling idle, no hard cap
Token Storage
SHA-256 server, OS keychain client
Snapshot Encryption
AES-256-GCM, scrypt-derived
Binary Signatures
Ed25519 (SHA-256 digest)
Transport (public)
HTTPS, TLS 1.2+
Transport (internal)
mTLS, Knockout CA v2
DB Constraint
is_encrypted OR legacy_plaintext
Backup Wrap
AES-256-CBC + pbkdf2
Backup Retention
30 days, OVH S3
Quantum Resistance
AES-256 (NIST post-quantum safe)

Open dashboard

Unlock your vault, browse sessions, manage API keys.

Full architecture

Deep-dive into key derivation, the lease pipeline, and threat model.