Trust & Safety
Security Policy
Your SSH credentials and session data are treated with the highest level of protection. This document explains exactly how — in plain language.
AES-256 Encryption at Rest
Every SSH password and private key you store is encrypted with AES-256-GCM before it is written to the database. The raw value is never stored.
TLS in Transit
All traffic between your browser and the server travels over TLS. SSH traffic through the terminal is tunnelled inside an encrypted WebSocket — it is never exposed in plaintext on the wire.
Mandatory Multi-Factor Auth
Every account requires TOTP-based MFA before accessing any terminal. Even if a password is compromised, an attacker cannot reach your servers without the second factor.
Zero-Knowledge Design
Administrators cannot read your decrypted credentials. The encryption key is derived at runtime and never logged, exported, or stored alongside the ciphertext.
Session Isolation
Each terminal session runs in an isolated subprocess. Sessions are bound to a single authenticated request — no session data bleeds across users or connections.
CSRF & XSS Hardening
Every state-changing request requires a cryptographic CSRF token. Content-Security-Policy headers prevent cross-site scripting. Cookies are HttpOnly and SameSite=Lax.
Credential Storage
When you add an SSH server, any password or private key you provide is encrypted immediately in the application layer using AES-256-GCM — a symmetric authenticated-encryption cipher — before being written to the database.
- The encryption key is derived from the application
SECRET_KEYand is never stored in the database. - The ciphertext includes an authentication tag; tampered data is rejected before decryption is attempted.
- Private keys are never written to disk in plaintext at any point.
- Database backups contain only ciphertext — they are useless without the application key.
How Credentials Flow During a Session
When you open a terminal, credentials follow a narrow, short-lived path:
- Your browser sends a signed, session-authenticated WebSocket handshake over TLS.
- The server decrypts the stored credential in memory only for the duration of the SSH handshake.
- The decrypted value is passed directly to the Paramiko SSH client and is never written to a log, file, or cache.
- When the session closes, the in-memory reference is released immediately.
Multi-Factor Authentication
MFA is enforced as a platform-level control — not optional per account.
- TOTP secrets are stored encrypted, in the same way as SSH credentials.
- Backup codes are hashed with bcrypt — the plaintext is shown once and never stored.
- An MFA session flag is recorded in the server-side session store (Redis). It cannot be spoofed by editing a cookie.
- Each TOTP code is accepted only once — replay attacks are blocked.
Authentication & Password Security
- Passwords are hashed using Django's default PBKDF2-SHA256 with a per-user salt — they are never stored in recoverable form.
- All login and registration forms include brute-force protections via rate limiting.
- Password reset tokens are single-use and expire automatically.
Transport Security
- All HTTP traffic is served via Nginx, which enforces TLS termination.
- WebSocket connections (terminal I/O) are carried over
wss://— the SSH byte stream is never exposed in the clear to the network. - HSTS is configurable per deployment; once enabled, browsers refuse to connect without TLS.
- Strict
X-Frame-Options: DENYandX-Content-Type-Options: nosniffheaders are set on every response.
What We Do Not Do
- We do not log terminal input or output.
- We do not share credential data with any third party.
- We do not store plaintext passwords, private keys, or TOTP secrets anywhere.
- We do not use third-party analytics or tracking scripts.
Reporting a Vulnerability
If you discover a security issue, please report it responsibly. Do not open a public GitHub issue — instead, contact the maintainer directly so the issue can be triaged and patched before disclosure.
Last reviewed: April 2026