> Security & Encryption
How Morpheus keeps your data safe with ECDH key exchange and TweetNaCl encryption.
ECDH Key Exchange
When you scan the QR code, the following happens:
- The QR code encodes the WebSocket URL and the agent's Curve25519 public key.
- The mobile app generates its own Curve25519 keypair and sends its public key to the agent.
- Both sides compute a shared secret using
nacl.box.before(theirPublicKey, mySecretKey). - The shared secret is never transmitted — it is derived independently on each device.
// Shared secret derivation
const sharedSecret = nacl.box.before(
theirPublicKey,
mySecretKey
);
TweetNaCl Encryption
All messages after pairing are encrypted using NaCl secretbox, which provides authenticated encryption with the XSalsa20-Poly1305 algorithm.
- A unique 24-byte random nonce is generated for every message.
- The nonce is prepended to the ciphertext and sent alongside it.
- The receiver decrypts using the shared secret and the nonce.
- Poly1305 MAC ensures messages cannot be tampered with.
// Encrypting a message
const nonce = nacl.randomBytes(24);
const encrypted = nacl.secretbox(message, nonce, sharedSecret);
Challenge-Response Verification
When a previously paired device reconnects, the server verifies its identity with a challenge-response protocol:
- The agent generates 32 random bytes and sends them to the mobile app.
- The mobile app computes
nacl.hash(challengeBytes)and sends back the base64-encoded result. - The agent independently computes the same hash and compares. If they match, the device is authenticated.
This prevents replay attacks and ensures only the original paired device can reconnect.
Instruction Sanitization
Commands sent to the AI agent are sanitized to mitigate prompt injection:
- Special characters and control sequences are escaped.
- Input length limits are enforced to prevent context window abuse.
- System prompts are isolated from user input to prevent override attempts.