Editorial introduction
Recognizes standard encryption, replay checks, pairing and HTTP controls in summarized source. Flags endpoint authority, key files, hosted code and supply-chain trust; browser and Swift code were not reviewed.
Reading scope: Summarized web reads of installer, Go crypto/pairing/replay, file keys and HTTP controls; no browser crypto, Swift bridge, setup or release-binary verification.
This is a limited public-web review of pinned source fcc905914 and the v2.1.3 release page, not a security certificate. No installation, exploit testing, binary verification or inspection of private production Cloud was performed. Some public directory/asset reads failed; Claude web fetches may provide summaries. An unreviewed mechanism or inference is not an established vulnerability.
The pinned README still selected v2.1.2 when reviewed; that observation is preserved. Later main commit 9e5a7ad updated it to v2.1.3. This rerun did not inspect the Swift native pairing bridge and cannot establish that concerns in the separate 2.1.1 report are resolved. The previous v2.1.2 response remains available for comparison.
Method: only public source/release URLs and the question were supplied, with repository context disabled. Visible tool records show network reads only. Each initial Codex job lacked network tools and was excluded as a technical failure; each was retried once. Valid outputs are preserved, including their status footers; this does not claim that all built-in instructions were removed. Full methodology.
Download the complete original English text · SHA-256 01e81e2af355d84a29c0ec3896b96fee16e9161a1e656a42d9c3ca597916b200
Complete original response
Verdict: I found no sign of malicious or deceptive behaviour, and the cryptography is built from standard parts. Installing it is not risk-free, though. The tool can read your Claude Code and Codex conversations, your project files and your terminals. It can also type commands into those terminals. Most of the risk comes from what that access allows if something goes wrong, not from a broken cipher.
How I checked: I read the source at commit fcc9059 (the commit release v2.1.3 points to) through GitHub’s web pages. My fetch tool summarizes pages, so I read summaries rather than full files. I did not download, run or verify any binary.
What the code confirms
Installer (install.sh)
- It checks the release manifest’s Ed25519 signature against one public key hardcoded in the script (
2Du3yZ4j…/O0=), using OpenSSL 3 and Python run in isolated mode (-I). - Only after that check passes does it compare the archive’s SHA-256 hash and size. Then it unpacks into
~/.local/share/clawdline-nextwith private file permissions. - It never uses
sudoand never pipes a download straight into a shell. The background service is created afterwards by the downloadedclawdline setupbinary, whose code I did not review.
Encryption of Cloud traffic (internal/domain/cloud/envelope.go)
- Message contents are encrypted with AES-256-GCM, using a fresh 12-byte random nonce from
crypto/randfor each message. - Each message is signed with the sending device’s Ed25519 key. The receiver rejects senders it hasn’t already pinned and checks the signature before decrypting.
- Replay protection works. The inbound path in
internal/adapters/cloud/transport.goruns: signature check → replay-window check (Replay.Claim) → decrypt.
Pairing a phone or browser (internal/domain/cloud/pairing.go)
- The two sides agree a key with X25519, which feeds an HKDF-SHA256 key derivation. The resulting key encrypts the handover with AES-GCM, and the authenticated data covers the pairing ID, the sender and the temporary public key.
- The browser’s offer is encrypted with a 32-byte secret carried in the QR code or link. The server stores only a hash of that secret.
- On this design, the relay can’t read or quietly alter a pairing.
Key storage (internal/adapters/cloudkeys/files.go)
- Keys are stored as plain base64 in files under
…/cloud/. The directory is owner-only (0700) and the files are 0600. Writes are atomic, and opens refuse symlinks (O_NOFOLLOWplus a same-file check). - The keys are not encrypted at rest. Any program running as your user can read them, and the macOS Keychain is listed as planned but not built.
Local web server (internal/transport/http/gate.go, docs/remote.md)
- It binds to 127.0.0.1 by default. It only accepts requests addressed to localhost or your Tailscale name, which defends against DNS-rebinding attacks.
- Cross-site requests are blocked using the Origin and Sec-Fetch headers and by requiring JSON bodies.
Risks and weak points
- A paired device controls your machine. A device with “read+send” permission can type into your terminals, and new pairings default to read+send. Anyone who sees a pairing link or QR code before you use it can pair instead of you. The same applies to a
clawdline openURL, which contains a full access token. - The web console’s code comes from the vendor’s server. The phone/browser viewer at
app.clawdline.comis loaded from Cloudflare Pages. Nothing like code signing or Subresource Integrity checks what gets served (docs/hosted-console.md). A compromised or malicious deployment could change the code that holds your keys. That weakens the claim that “the relay only carries ciphertext”: you are still trusting whoever runs the website. - Trust in the release process. The release signing key is a GitHub Actions secret, gated behind an
environment: releaseapproval. Whoever controls the maintainer’s GitHub account and that secret can ship a validly signed update. Several actions are pinned to version tags rather than exact commits. The project itself says releases are not yet reproducible. - Metadata isn’t hidden. It encrypts content but not the message envelope. The Cloud relay sees your account, devices, channels (which include machine and session IDs), timing, message sizes and IP address. STUN servers at Cloudflare and Google see your IP when a direct connection is attempted. Even with Cloud off, it contacts
app.clawdline.com/BUILD.jsonand GitHub for update checks. - Smaller issues:
- The envelope’s metadata is bound only by the signature (encryption covers no associated data), and there is no timestamp freshness check.
- The cookie gets the
Secureflag based on a header the client controls (X-Forwarded-Proto). - The recovery code is the raw content key.
- Some design docs are out of date.
docs/cloud-wire.mdsays the Go pairing and replay protection aren’t implemented, but the code has both.
What I couldn’t verify
- The binaries. I didn’t download any. Whether the v2.1.3 tarballs or DMG match this source, the Sigstore/SLSA attestations, notarization and
SHA256SUMSare all unchecked. - The Clawdline Cloud servers (relay and API). They are closed source, so their logging, retention and deployed configuration are unknown.
- The browser-side crypto (
web/) and how the browser stores keys. - Swift code. I listed the macOS app’s code in
shell/darwin/but didn’t review it. The files the docs name (CloudEnvelope.swift,CloudKeys.swift) didn’t appear in that partial listing. - Other code paths. I didn’t review
clawdline setup(the service it installs), the auto-updater, push notifications, or the constant-time token comparison inauth. - The installer pin. The README’s install command still pins v2.1.2, not v2.1.3.
Recommendations if you install
- Use local-only mode (Cloud is off by default).
- Pair only your own devices, and choose read-only unless you need to send.
- Revoke devices you no longer use.
- Before running anything, check the attestation with
gh attestation verify <file> --repo sainteye/clawdline.
My web searches turned up nothing about Clawdline, only the unrelated OpenClaw project, so I have no outside reputation information.
Sources: