Security
Daisy sends your keyboard and pointer only to systems you paired, encrypted and authenticated, with no account, server or telemetry. The controls behind that are below.
Cryptography
- Protocol
- Noise XX (Noise_XX_25519_ChaChaPoly_BLAKE2s), mutually authenticated, with ephemeral keys for forward secrecy
- Key agreement
- X25519 (Curve25519 ECDH, 128-bit security level)
- Encryption
- ChaCha20-Poly1305 AEAD, 256-bit keys
- Hash
- BLAKE2s
- Integrity and replay
- Every message authenticated; per-direction nonces reject altered, replayed and reordered messages
- Version binding
- Protocol versions exchanged and authenticated in the handshake
Device identity
- Device key
- Non-exportable Secure Enclave P-256 signing key per system
- Session authentication
- ECDSA-SHA256 proof over each Noise handshake hash and connection role, checked against the pinned device key
- Noise key
- Separate long-term X25519 key; possession alone does not authorize a session
- Storage
- Device key in the Data Protection Keychain with AfterFirstUnlockThisDeviceOnly protection; identity files contain the Noise key and a Keychain reference
- Reconnect
- Device signing requires no Touch ID or password prompt
- Rotation
- Supported; invalidates every existing pairing
Pairing
- Authentication
- SPAKE2 password-authenticated key exchange over the Ed25519 group, keyed by a one-time six-digit code
- Key confirmation
- HMAC-SHA256 over the Noise handshake hash, role-labelled against reflection
- Result
- Peer Noise and device public keys pinned together after mutual confirmation
- Guessing resistance
- One guess per code; at most five unknown-key attempts per ten minutes; one pairing at a time
- Consent
- A sharing system accepts a new one only while it has no peers, for 30 seconds after Add a System, or with Always discoverable on; unknown keys are refused otherwise
- Timeouts
- Handshake 15 seconds; pairing two minutes
Trust lifecycle
- Policies
- Expiry after 4 days unused (default; any number of hours or days), single session, or until revoked; a fixed term in days from the command line
- Enforcement
- Each system enforces its own policy; a session requires mutual trust, so the stricter policy applies
- Revocation
- Immediate from the app; within one second for changes made outside it; expired trust purged
Input safety
- Local override
- Control-Option-Command-Escape returns control to the local system
- Liveness
- Sessions terminate after three seconds without traffic
- Input release
- All held keys and buttons released whenever a session ends
- Display activity
- Only the current control owner at the current generation can refresh an unlocked, locally idle peer’s display timeout
- Fail-safe
- Capture never blocks; on overload, input stays local and the session terminates
Network and data
- Connections
- Direct TCP between paired peers only (default port 24850, configurable bind address)
- Data sent
- System name, public key, pairing and liveness messages, display activity updates, input events, control handoffs, opted-in developer diagnostics, the clipboard when control crosses and the receiving system lacks it (switchable), and copied-file contents requested from a live offer
- Data not sent
- No screen capture
- Release requests
- HTTPS to the update feed and GitHub release archives; no account or access token
- Developer diagnostics
- Opt-in traces stream only over negotiated authenticated peer sessions, with bounded queues and input priority; local collector and output are private to the account
- Third parties
- No peer input or clipboard is sent to third parties. No telemetry, analytics or relays
Release integrity
- Build
- Release workflow only, from a tagged commit
- Signing
- Developer ID signed and notarized by Apple
- Provenance
- SLSA Build Level 3 provenance and GitHub artifact attestation
- Update verification
- Ed25519-signed feeds and archives, with the update public key embedded in the signed application
- Compatibility
- Routine updates retain the current major version and every supported network protocol through signed feed channels
- App identity
- Notarized Developer ID app with the installed publisher and bundle identifier
- Recovery
- Failed updates report an error; manual installation is available through Homebrew or the notarized DMG