Security First
We can't read your terminal data. Not because we promise not to - because it's mathematically impossible.
Zero-Knowledge Design
Your terminal data is encrypted on your machine before transmission. Our servers only see encrypted bytes. Even if our servers were compromised, attackers would only get encrypted data they cannot decrypt.
How It Works
1 Key Exchange
When your mobile app connects to a session, it performs an X25519 ECDH key exchange with the desktop wrapper. This establishes a shared secret that only your devices know.
# Wrapper generates ephemeral key pair
wrapper_private = X25519.generate()
wrapper_public = wrapper_private.public_key()
# Client generates ephemeral key pair
client_private = X25519.generate()
client_public = client_private.public_key()
# Both derive the same shared secret
shared_secret = ECDH(my_private, their_public)
2 Encryption
All terminal data is encrypted using AES-256-GCM with the shared secret. Each message has a unique nonce to prevent replay attacks.
# Wrapper encrypts terminal output
nonce = random_bytes(12)
ciphertext = AES-256-GCM.encrypt(
key=shared_secret,
nonce=nonce,
plaintext=terminal_output
)
# Send encrypted data through server
send(nonce + ciphertext) # Server can't decrypt
3 Server Role
Our server acts as a dumb relay. It routes encrypted bytes between your wrapper and mobile app, but cannot decrypt them. The server handles:
- Authentication (JWT tokens, magic links)
- Session management (connect wrapper to clients)
- Message routing (encrypted bytes only)
Defense in Depth
We don't rely on a single security layer. AFK uses multiple independent protections:
End-to-End Encryption
X25519 + AES-256-GCM between wrapper and clients
Token Authentication
Short-lived JWTs with refresh tokens, magic link login
Transport Security
All connections use TLS 1.3 (HTTPS/WSS)
Session Isolation
Each user's sessions are cryptographically isolated
Open Source
Don't trust us - verify. The AFK client and wrapper are open source. You can audit the encryption implementation yourself.
View on GitHub