Skip to content

Repository files navigation

LeaveSafe

Leave your laptop. Stay safe.

A lightweight, cross-platform device security monitor that turns your phone into a remote alarm system — no cloud, no accounts, just a QR code scan.


CI Go License Platforms

Windows Linux macOS Intel macOS ARM


Getting Started | Features | How It Works | Configuration


What is LeaveSafe?

LeaveSafe runs on your laptop as a terminal dashboard and lets you arm a security monitor from your phone by scanning a QR code. Once armed, it watches the laptop's sensors (charger, lid, USB, screen lock, network, input) and sends instant alerts to your phone if anything changes while you're away.

No internet connection required. Communication is local-only over WebSocket or Bluetooth Low Energy (BLE), secured with a 16-digit Luhn-validated pairing key.


Features

Pairing & Connection

  • QR Code Pairing — Scan once from your phone's browser, no app required
  • Dual Transport — Connect via Wi-Fi (WebSocket) or Bluetooth Low Energy (BLE)
  • No Cloud, No Accounts — Everything stays on your local network

Monitoring

  • Multi-Sensor Monitoring — Power/charger, lid, USB, screen lock, network, and input changes
  • Auto-Arm on Screen Lock — Optionally arm automatically when you lock your laptop
  • Sensor Pause / Disable — Dismiss an alarm by pausing a sensor temporarily or disabling it permanently

Alarm

  • Volume Escalation — Configurable levels: notify phone only, medium volume, then full volume
  • Local Siren — Alternating tone alarm sounds directly on the laptop
  • Graceful Alarm — Triggers automatically if all clients disconnect while armed
  • PIN Protection — Optionally require a PIN code to disarm

Security

  • Rate Limiting & Lockout — 5 failed auth attempts triggers a 60-second lockout
  • Session Management — Maximum 3 concurrent authenticated clients
  • 256-bit Session Tokens — Random hex tokens, never reused
  • Event Audit Log — All security events recorded in JSONL format with timestamps

Interface

  • Live TUI Dashboard — ASCII terminal UI with QR code, live logs, and system status
  • Mobile Web UI — Responsive, dark-themed phone interface served directly from the binary
  • Interactive Terminal Commands — Test alerts, trigger sensors, view history, rotate keys

Deployment

  • Cross-Platform — Native sensor implementations for Windows, Linux, and macOS
  • Single Binary — No dependencies, just download and run
  • Configuration Persistence — Settings saved in JSON format across sessions

How It Works

graph LR
    subgraph LAPTOP ["Laptop"]
        TUI["TUI Dashboard"]
        SM["Sensor Monitor"]
        WS["WebSocket / BLE Server"]

        TUI --> SM
        SM --> WS
    end

    subgraph PHONE ["Phone / Tablet"]
        BR["Browser"]
        CTRL["Arm / Disarm"]
        ALERT["Alert Cards"]
    end

    TUI -- "QR Code" --> BR
    BR -- "Authenticate" --> WS
    CTRL -- "Control" --> WS
    WS -- "Real-time Alerts" --> ALERT

    style LAPTOP fill:#1a1a2e,stroke:#16213e,color:#e6e6e6
    style PHONE fill:#0f3460,stroke:#16213e,color:#e6e6e6
    style TUI fill:#533483,stroke:#2c2c54,color:#fff
    style SM fill:#533483,stroke:#2c2c54,color:#fff
    style WS fill:#533483,stroke:#2c2c54,color:#fff
    style BR fill:#e94560,stroke:#c81d4e,color:#fff
    style CTRL fill:#e94560,stroke:#c81d4e,color:#fff
    style ALERT fill:#e94560,stroke:#c81d4e,color:#fff
Loading

Sensors

graph LR
    P["Power / Charger"] ~~~ L["Lid Open / Close"] ~~~ U["USB Devices"]
    S["Screen Lock"] ~~~ N["Network / IP"] ~~~ I["Input Events"]

    style P fill:#00b4d8,stroke:#0096c7,color:#fff
    style L fill:#00b4d8,stroke:#0096c7,color:#fff
    style U fill:#00b4d8,stroke:#0096c7,color:#fff
    style S fill:#0077b6,stroke:#005f8a,color:#fff
    style N fill:#0077b6,stroke:#005f8a,color:#fff
    style I fill:#0077b6,stroke:#005f8a,color:#fff
Loading

Pairing Flow

sequenceDiagram
    participant L as Laptop
    participant P as Phone

    L->>L: Generate 16-digit pairing key
    L->>L: Display QR code in terminal
    P->>L: Scan QR code / open URL
    P->>L: Authenticate with pairing key
    L->>P: Session token (256-bit)
    P->>L: Arm
    L->>L: Start monitoring sensors

    loop While Armed
        L-->>P: Real-time sensor alerts
    end

    P->>L: Disarm
    L->>L: Stop monitoring
Loading

Getting Started

Download Binary

Grab the latest pre-built binary from the Releases page.

Platform File
Windows 64-bit leavesafe-windows-amd64.exe
Linux 64-bit leavesafe-linux-amd64
macOS Intel leavesafe-darwin-amd64
macOS Apple Silicon leavesafe-darwin-arm64

macOS: First-time setup

macOS blocks unsigned binaries by default. After downloading, run these commands in Terminal to make it executable:

# 1. Grant execute permission
chmod +x leavesafe-darwin-arm64

# 2. Remove the quarantine attribute added by macOS Gatekeeper
xattr -d com.apple.quarantine leavesafe-darwin-arm64

# 3. Run it
./leavesafe-darwin-arm64

Note: Replace leavesafe-darwin-arm64 with leavesafe-darwin-amd64 if you are on an Intel Mac.

If you still see a "cannot be opened" warning, go to System Settings > Privacy & Security and click Open Anyway next to the LeaveSafe entry.

Build from Source

# Requires Go 1.25+
git clone https://github.com/atakankizilyuce/LeaveSafe.git
cd LeaveSafe

# Build for your current platform
go build -o leavesafe ./cmd/leavesafe

# Or use the Makefile to build all platforms
make all

Development Checks

Every pull request has to pass the same gate, and all of it runs locally:

make fmt        # gofmt
make vet        # go vet
make lint       # golangci-lint (staticcheck, gosec, revive, errcheck, ...)
make web-lint   # biome, for web/*.js
make vuln       # govulncheck
make test       # unit tests
make check      # all of the above

The CI workflow adds a few things a laptop cannot cover on its own:

Job What it does
format gofmt plus a check that go.mod/go.sum are tidy
typos spell check across the repo (typos, configured in _typos.toml)
lint golangci-lint once per target OS — half this codebase sits behind build tags, so a single platform never sees all of it
test unit tests on Linux, Windows and macOS, with coverage reported in the run summary
e2e starts the real binary on each OS and drives the whole user flow over a real WebSocket
realtrigger fires the hardware changes each runner genuinely permits, and records every one it cannot
sandbox-linux boots a real Linux VM under QEMU/KVM and creates real kernel-backed hardware
frontend Biome lint and format check on the embedded web client
build the full five-target release matrix
vulncheck govulncheck against the Go toolchain and dependencies

ci-success aggregates all of them, so branch protection only needs that one required check. Dependency and action updates arrive weekly through Dependabot.

How much this proves

Every run publishes a coverage matrix naming each sensor that was genuinely triggered and each one that could not be, with the reason. No test fakes hardware and reports success: where a real trigger is impossible, it is skipped and the gap is stated.

In the Linux VM the charger is genuinely unplugged through the test_power kernel module and the real binary reads the change from a real /sys. On Windows real pointer activity is synthesised and the input sensor fires; real IP changes are detected on all three. Everything else skips with a measured reason rather than a fake pass — what no CI environment can reach is listed in docs/manual-verification.md.

Run the layers locally with make test-e2e, make test-realtrigger and make test-sandbox; plain make test stays fast and touches no hardware.


Usage

./leavesafe          # normal mode
./leavesafe -dev     # development mode (serves web assets from filesystem)

The terminal dashboard opens with:

  • A QR code on the left — scan it with your phone
  • A status panel on the right showing armed state, connected clients, active sensors, and the pairing key
  • A live log area at the bottom

Terminal Commands

Command Description
test Send a test alert to all connected clients
trigger <sensor> Manually trigger a specific sensor (power, lid, usb, screen, network, input)
stop / silence Stop an active alarm
history Show the last 20 security events
rotate-key Generate a new pairing key and invalidate all sessions
help Show available commands
Ctrl+C Graceful shutdown

On your phone: Open the URL shown in the terminal (or scan the QR code), authenticate, and use the Arm / Disarm buttons. You can also enable/disable individual sensors and configure alarm settings from the phone UI.


Platform Support

Feature Windows Linux macOS
Power / Charger
Lid open / close
USB connect / disconnect
Screen lock / unlock
Network / IP change
Input (keyboard/mouse)
Bluetooth Low Energy
Local alarm siren

Configuration

Settings are stored in a JSON file and persist across sessions:

OS Path
Windows %APPDATA%\LeaveSafe\config.json
Linux / macOS ~/.leavesafe/config.json

You can change settings from the phone UI or by editing the file directly.

All configuration options
Setting Default Description
port 0 (auto) HTTP server port
max_sessions 3 Maximum concurrent clients
max_auth_attempts 5 Failed attempts before lockout
lockout_seconds 60 Lockout duration
heartbeat_seconds 15 Status broadcast interval
disconnect_grace_seconds 30 Delay before alarm on full disconnect
auto_arm_on_lock false Arm automatically when screen locks
connection_mode wifi Transport mode (wifi or bluetooth)
pin_protection.enabled false Require PIN to disarm
alarm.escalation_enabled false Enable volume escalation levels
enabled_sensors.* varies Toggle individual sensors on/off

Security Model

Layer Detail
Pairing Key 16 digits with Luhn check digit, generated fresh each run
Session Tokens 256-bit random hex strings, never reused
Rate Limiting 60-second lockout after 5 failed auth attempts
Session Limit Maximum 3 concurrent connections
Disconnect Alarm Triggers after 30-second grace period if all clients drop while armed
Local-Only No data ever leaves your LAN

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Commit your changes
  4. Open a Pull Request

Run tests before submitting:

go test ./... -v -race

License

Distributed under the Apache License 2.0.


Made with Go

About

Leave your laptop. Stay safe. A lightweight, cross-platform device security monitor that turns your phone into a remote alarm system — no cloud, no accounts, just a QR code scan.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages