Editorial introduction
Recognizes signature checks, content encryption and protected pairing; flags device authority, file-based keys and untraced revocation/key rotation.
Reading scope: About 15 security files via summarized web reads; setup, browser key storage and revocation wiring not fully traced.
The v2.1.2 release URL also supplied to the reviewer
This response concerns pinned source 239adc8ad and v2.1.2. That source’s README still selects v2.1.1; the later main branch selects v2.1.2. This is not evidence that the v2.1.2 release is missing. Untraced authentication or key-rotation wiring is not proof that those mechanisms are absent.
Download the complete original English text · SHA-256 d8a61fb19237ff2e3bf1a96f22749318fe939aa15dec417194a1aa71e30850c5
Complete original response
I don’t see a red flag in this tool. The installer and the encryption are carefully built, and I found nothing that looks hidden or malicious. Most of the real risk comes from what the tool does by design, not from installing it.
What I couldn’t check: My page fetcher returns summaries, not raw source, and I read about 15 key files rather than the whole repository.
How installing works
- Signed downloads.
install.shverifies a signed release list (Ed25519, through your local OpenSSL 3) against one public key built into the script. It then checks the download’s size and SHA-256. I found no path that installs anything unchecked. It uses nosudoand noeval. - User-level only. Files go under
~/.local/share/clawdline-nextand~/.config/clawdline-next. The release’s ownsetupcommand creates the background service, but I didn’t read that code. - Updates. Updates must be signed by a key built into the running program. Automatic updates are off by default. Going back to an older version requires
--force. - Where the signing key lives. It’s a GitHub Actions secret behind a maintainer-approval step, plus one offline copy. If the maintainer’s GitHub account or that secret leaked, an attacker could ship a validly signed bad release. Releases also carry GitHub build-provenance attestations, and the macOS builds are notarized.
Encryption with Cloud turned on (Cloud is off by default)
- The basics. Content is encrypted with AES-256-GCM using a random 12-byte nonce, and each message is signed with Ed25519. The signature is checked before anything is decrypted, and messages from unknown senders are refused. Replayed messages are rejected.
- Pairing a browser. This uses a standard key exchange (X25519 and HKDF-SHA256). The browser’s offer is encrypted with a secret kept in the link’s
#pair=part, which never reaches the server; the server only gets a hash of it. That should stop Cloud from swapping in its own key. You also compare 16-character fingerprints on both screens. - What Cloud can see. Account and device IDs, channel names, timing, message sizes and your IP address, but not the content.
Risks that come with the design
- A paired device can control your machine. The README says it can send instructions or use a terminal, which means it can run code. Anyone who gets a pairing link while it’s valid gets that access. Pairing offers expire after 10 minutes. The code comments say a link can be claimed only once, but that check isn’t in the file I read.
- Removing a device doesn’t change the key. Each machine has one content key shared with every paired browser. Removing a device stops the machine from accepting its requests, but the docs describe no key-change step. A removed browser still holds the key, which matters if it ever gets traffic through Cloud or a leak. A
rekey.gofile exists, but I didn’t check whether removal triggers it. - Keys are plain files. The local keys are files readable only by your user account, not stored in hardware. Anything running as you can read them.
- Some network traffic happens even with Cloud off. Update checks go to GitHub and
app.clawdline.com/BUILD.json. Direct phone connections ask STUN servers run by Google and Cloudflare, which see your IP address. - Notifications can show plaintext. Push titles and bodies can appear in readable form on a phone’s lock screen.
- Local web access is reasonably protected. The local web server only accepts
localhostnames or your Tailscale name, which guards against DNS-rebinding attacks. It also checks where requests come from and usesSameSite=Strictcookies.
What I couldn’t confirm from the code
- That the published v2.1.2 files were actually built from this source. The builds aren’t documented as reproducible, so you’re trusting the CI pipeline.
- How the Cloud server behaves, what it stores and for how long. Its code isn’t public, and the project’s docs say this too.
- That the
machine_signing_keysent to browsers is a public key and not the private one. The comments say it’s public, but I didn’t trace where it’s created. - Whether passwords and tokens are compared in constant time (
auth.VerifyandVerifySecret). - How the browser stores its keys, and whether the key objects can be exported.
- What the
whisper(transcription),healthuploadandpushparts of the program send, if anything.
Recommendation
Installing it is reasonable if you trust this maintainer and GitHub. To keep risk low:
- Leave Cloud off unless you need it.
- If you turn it on, use
clawdline cloud commands offwhen you only need to read, and pair only devices you trust. - Treat pairing links like passwords.
- Leave automatic updates off if you’d rather review each release first.
One small thing: at this commit the README tells you to install --version v2.1.1, not v2.1.2. Use --version v2.1.2 if you want this release.