Security Whitepaper
Overview
Termly provides end-to-end encrypted communication between your development machine and mobile device. All terminal output and input is encrypted before transmission, ensuring that your code, credentials, and development work remain completely private.
Encryption Architecture
Algorithm: AES-256-GCM
- Cipher: AES (Advanced Encryption Standard) with 256-bit keys
- Mode: GCM (Galois/Counter Mode) providing both confidentiality and authenticity
- Authentication: Built-in message authentication preventing tampering
- IV Size: 96-bit (12 bytes) unique per message
Key Exchange: Diffie-Hellman 2048-bit
- Algorithm: Diffie-Hellman (DH) with RFC 3526 Group 14 (modp14)
- Prime Size: 2048-bit (equivalent to ~112-bit symmetric security)
- Generator: 2 (standard generator for Group 14)
- Key Derivation: HKDF-SHA256 with info string "termly-session-key"
- Forward Secrecy: New ephemeral keys for each session
Key Rotation
Each terminal session generates a unique encryption key. When you connect to a different session or reconnect after disconnection, a new key exchange is performed. Keys are never reused across sessions.
Pairing Flow
- CLI Generates Pairing Code: A unique 6-character code is created and stored on the server
- QR Code Display: The pairing code is encoded in a QR code displayed in the terminal
- Mobile Scans QR: The iOS app scans the QR code to retrieve the pairing code
- Key Exchange Initiation:
- CLI generates an ephemeral DH-2048 key pair using RFC 3526 Group 14
- CLI sends its public key to the server along with the pairing code
- Mobile generates its own ephemeral DH-2048 key pair (same parameters)
- Mobile sends its public key to the server via REST API
- Server forwards mobile's public key to CLI via WebSocket
- Both sides compute the DH shared secret independently
- Shared Secret Derivation: Both sides use HKDF-SHA256 to derive a 256-bit AES key from the DH shared secret
- Fingerprint Verification: A 6-character fingerprint (first 6 chars of SHA-256 hash of the shared secret) is displayed on both devices for manual verification (optional but recommended)
- Secure Channel Established: All subsequent messages are encrypted with AES-256-GCM
Message Format
Encrypted Message Structure
{
"type": "output" | "input",
"encrypted": true,
"data": "<base64-encoded-ciphertext>",
"iv": "<base64-encoded-initialization-vector>",
"seq": <sequence-number>,
"timestamp": "<ISO8601-timestamp>"
}Encryption Process
- Generate a random 96-bit IV
- Encrypt plaintext using AES-256-GCM with the shared key and IV
- Base64-encode the ciphertext and IV
- Send the encrypted message with metadata
Security Properties
Confidentiality
- All terminal I/O encrypted end-to-end
- Server cannot decrypt messages (zero-knowledge architecture)
- Network observers see only encrypted data
- 256-bit key strength provides long-term security
Integrity & Authenticity
- GCM mode provides built-in authentication tags
- Tampered messages are detected and rejected
- Replay attacks prevented by sequence numbers
- Message ordering guaranteed by server
Forward Secrecy
- Ephemeral DH keys never stored permanently
- Compromise of one session doesn't affect others
- Keys derived fresh for each session
- Old session data cannot be decrypted even if device is compromised
Key Storage
Mobile Apps (iOS & Android)
- iOS: Keys stored in iOS Keychain with
kSecAttrAccessibleWhenUnlocked - Android: Keys stored in Android Keystore with encryption at rest
- Keys isolated per session on both platforms
- Automatic cleanup when session is deleted
- Never backed up to cloud services
CLI (Agent)
- Keys stored in memory only
- Cleared immediately after session ends
- Never written to disk
- Process memory protected by OS
Privacy Guarantees
- No Logging: Terminal content never logged by server
- Metadata Minimization: Server only stores session IDs and connection timestamps
- One Device Per Session: Enforced to prevent unauthorized access
- Automatic Cleanup: Stale sessions automatically deleted after 24 hours
- No Analytics: No tracking, telemetry, or usage analytics collected
Threat Model
Protected Against
- Network eavesdropping (man-in-the-middle attacks)
- Compromised or malicious server
- Replay attacks
- Message tampering
- Unauthorized device connections
Not Protected Against
- Compromised development machine (malware, keyloggers)
- Compromised mobile device
- Physical access to unlocked devices
- Social engineering attacks
Best Practices
- Verify Fingerprints: Always verify the 6-character fingerprint when pairing
- Delete Old Sessions: Remove sessions you're no longer using
- Use Strong Passwords: Protect your Termly account with a strong unique password
- Keep Software Updated: Update both the iOS app and CLI regularly
- Secure Your Devices: Use device passwords, biometrics, and full-disk encryption
Responsible Disclosure
If you discover a security vulnerability, please email us at hello@termly.dev with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if applicable)
We commit to responding within 48 hours and will work with you to understand and address the issue promptly.
Summary
Termly provides military-grade end-to-end encryption for your development workflow. Your code and credentials are protected by industry-standard cryptography, and the zero-knowledge architecture ensures that even we cannot access your data. Combined with forward secrecy and secure key storage, Termly offers a robust security model for mobile AI-assisted development.
Last updated: October 2025 • Version 1.0
← Back to Home