Skip to content

About

Secure cross-platform development mesh for remote iOS, Android, macOS, Windows, and Linux device workflows.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

DeviceLane

Develop on any computer. Build and test on every device.

DeviceLane is a secure, self-hosted development mesh. It connects Windows, macOS, and Linux hosts with the iOS and Android devices attached to them, then exposes those capabilities to authorized clients over the network.

The primary use case is cross-platform mobile development: work from Windows while a Mac builds, signs, launches, tests, and diagnoses an iOS app; or work from macOS while a Windows or Linux host operates an Android device through ADB.

Important

DeviceLane is currently an experimental developer preview. Its automated protocol and integration tests are extensive, but the physical-iPhone release gate has not yet been completed. Do not expose its ports directly to the public internet.

What it provides

  • Remote process and tool execution on registered development hosts
  • Discovery of connected iOS devices, simulators, Android devices, and emulators
  • Apple workflows through Xcode, xcodebuild, devicectl, simctl, xcresulttool, xctrace, and lldb-dap
  • Android workflows through ADB-capable agents
  • Remote project workspaces with path confinement
  • App build, install, launch, test, log, diagnostic, and artifact operations
  • Exclusive device leases so concurrent clients cannot control the same device accidentally
  • Reconnectable jobs with ordered events and request deduplication
  • Mutual TLS identities, explicit one-time pairing, peer allowlists, and audit records

How it works

Developer / automation
        |
        | mesh-cli (mutual TLS)
        v
  mesh-registry  <------>  mesh-agent on macOS  <------>  Xcode / iPhone / Simulator
        |
        +--------------->  mesh-agent on Windows <----->  ADB / Android
        |
        +--------------->  mesh-agent on Linux   <----->  tools / Android

The registry is the control plane. Agents advertise host and device capabilities. Clients select a host and device, obtain a lease, submit a job, and receive ordered output, diagnostics, and artifacts. Platform-restricted work stays on the platform that can legally and technically perform it: iOS builds still execute on a Mac with Xcode.

Current status

Area Status
Secure registry, agent, and CLI transport Implemented
Pairing, identities, allowlists, and audit trail Implemented
Remote jobs, reconnect, deadlines, and artifacts Implemented
Apple discovery, build, install, launch, XCTest, diagnostics Implemented and fixture/integration tested
macOS LaunchAgent bootstrap Implemented
Physical iPhone end-to-end validation iPhone-Hardware-Gate pending
Android adapter and ADB workflow Protocol foundation present; Android-Hardware-Gate pending
Public-internet deployment Not supported; use a trusted LAN or private VPN

Requirements

All hosts

  • Git
  • A current stable Rust toolchain installed with rustup
  • Network reachability between the controller and agents

Apple development host

  • macOS with full Xcode installed and selected
  • Accepted Xcode license
  • For physical devices: an unlocked and trusted iPhone, Developer Mode, and valid signing credentials

Android development host

  • Android SDK Platform Tools with adb available in PATH
  • For physical devices: USB debugging enabled and the host authorized

Quick start

Install prebuilt commands

With Node.js 20 or newer, install the npm launcher. On first use it downloads the matching GitHub Release binary and verifies its SHA-256 checksum:

npm install --global devicelane
devicelane --version

This provides devicelane (the client), devicelane-agent, and devicelane-registry. Native archives and checksums are also available directly from GitHub Releases.

Desktop installers

The desktop release produces a Windows MSI, a hardened and notarized macOS DMG, and Linux AppImage and deb packages. Pull-request artifacts are explicitly named unsigned-ci-*; they are short-lived test outputs and must not be redistributed as production builds. A production candidate is emitted only by the protected manual workflow after native platform signing, Apple notarization inputs, SHA-256 manifests, a CycloneDX SBOM, and a signed checksum bundle are available.

Install production packages only into the platform installer's administrator-owned location. DeviceLane checks the staged sidecar hash during packaging, but a hash check does not eliminate time-of-check/time-of-use races in a writable install directory. The signed, non-user-writable installation root is the security boundary. The per-user lifecycle tools preserve identity and logs during repair and normal uninstall; delete those directories separately only when rotating the device identity intentionally.

The native installer contains the desktop executable, devicelane-service, and the equal devicelane CLI client. The lifecycle and smoke tooling resolves both command binaries below the verified native installation root, rejects links/reparse points, and never substitutes a raw target/release binary for an installed artifact.

Release builds pin the hosted runner image (windows-2025, macos-15, or ubuntu-24.04), its exact image version, Rust 1.95.0, Node.js 22.20.0, every GitHub Action by commit, the native Xcode/SDK or MSVC/WiX toolchain, Linux package versions, Cargo.lock, and desktop/package-lock.json. Production aborts when an observed input differs from the protected repository-variable pins. SOURCE_DATE_EPOCH, UTC, non-incremental compilation, and two clean unsigned builds provide a reproducibility gate for unsigned payloads and configuration; their normalized installed-file manifests must match before CI accepts an artifact. Native container hashes are recorded where the format is deterministic.

The normalized comparison covers file-system semantics as well as bytes: entry type, executable or Unix permission mode, symbolic-link target, macOS extended attributes, and relevant Windows file attributes and ACL SDDL. Release files retain their bundle-relative paths during collection; an attempted destination collision aborts the workflow.

Each artifact set includes BUILD-INPUTS.txt with the observed versions and input hashes. The signed envelope is intentionally outside the unsigned payload comparison: signing services add external timestamp and notarization evidence, so the signed MSI/DMG container need not be bit-for-bit identical to its unsigned envelope. Production acceptance is not weakened: native signature verification, the single-DMG notarization and stapling gates, checksums, SBOMs, and signed checksum evidence must all succeed.

Each production platform has its own protected job. Credentials are unavailable while dependencies and unsigned payloads are built, and are injected only into the individual import, signing, or notarization step that needs them. Windows signing additionally pins the certificate subject and thumbprint, selects that certificate explicitly, verifies the resulting Publisher, and removes the temporary certificate and PFX. Linux package smoke tests exercise the packaged lifecycle script in an isolated home/runtime with a process-backed systemd adapter and perform real dpkg install and uninstall transactions on the hosted runner.

On macOS, the complete Tauri application and all build hooks finish without Apple credentials. The validated .app is then processed only by native codesign, hdiutil, notarytool, and stapler commands. Its temporary keychain is removed and the prior keychain search list restored before any smoke or SBOM step. Build jobs have no OIDC token permission; a separate protected attestation job receives only the already checked artifact digests and holds the minimal short-lived OIDC grant. Real deb transactions additionally require the hosted-CI gate and refuse to alter an already installed package.

Build from source

The examples use port 7443 for normal mutual-TLS traffic and temporary ports 7444/7445 for initial pairing. Replace CONTROLLER_HOST with a private DNS name or LAN/VPN address reachable from the other host.

1. Build the controller on Windows

git clone https://github.com/HECer/devicelane.git
cd devicelane
.\scripts\setup-windows.ps1

Start a temporary client-pairing listener:

.\target\debug\mesh-registry.exe pair --listen 127.0.0.1:7444 --identity .mesh\registry

In a second terminal, pair the local CLI:

.\target\debug\mesh-cli.exe pair --address 127.0.0.1:7444 --identity .mesh\cli

2. Pair and install a Mac agent

On the controller, temporarily permit inbound TCP 7445 only from the Mac's private IP, then run the following, replacing 192.168.0.61 with the controller's numeric private LAN or VPN interface address:

.\target\debug\mesh-registry.exe pair --listen 192.168.0.61:7445 --identity .mesh\registry

On the Mac, from the cloned repository:

sh ./scripts/setup-mac.sh --controller 192.168.0.61

Use the same controller address on the Mac. IPv6 ULA addresses use brackets in the listener command, for example --listen [fd12:3456::61]:7445, and no brackets in --controller fd12:3456::61. Pairing rejects wildcard, hostname, and public listener addresses. The setup dry run prints a pairing command for private IPv4 and ULA addresses; other forms receive guidance to choose a numeric private interface. Hostnames remain supported for registry transport. A private bind limits exposure; the legacy pairing exchange still sends its code in-band.

The setup script builds release binaries, pairs the agent, installs a per-user LaunchAgent, validates the Apple toolchain, starts the service, and prints the exact registry command required for that agent. Close firewall port 7445 immediately after pairing.

3. Start the registry

Run the NEXT_CONTROLLER_COMMAND printed by the Mac installer. It has this form:

.\target\debug\mesh-registry.exe --listen 0.0.0.0:7443 --identity .mesh\registry --offline-after-ms 5000 --agent-peer MAC_AGENT_ID

Allow TCP 7443 only from trusted clients and agents on your LAN or private VPN.

For a persistent per-user Windows controller, install or repair a Scheduled Task with the explicit agent peer ID printed by the Mac installer:

.\scripts\setup-windows.ps1 --controller-install `
  --agent-peer MAC_AGENT_ID `
  --controller-listen 0.0.0.0:7443 `
  --controller-identity "$env:LOCALAPPDATA\DeviceLane\registry\identity" `
  --controller-log-dir "$env:LOCALAPPDATA\DeviceLane\registry\logs"
.\scripts\setup-windows.ps1 --controller-status
.\scripts\setup-windows.ps1 --controller-uninstall

Installation and repair require explicit --agent-peer, --controller-listen, --controller-identity, and --controller-log-dir values. The Scheduled Task launches a PowerShell logging wrapper whose command contains only the deployed registry path and public runtime arguments; private keys and pairing secrets remain in the identity directory. A repair builds and stages a new per-user binary before briefly stopping and replacing the running controller. Re-running --controller-install repairs the current user's task idempotently. Uninstall removes only that user's task and preserves the deployed binary, identity, and logs.

Do not expose the registry to the public Internet. Permit inbound TCP 7443 in Windows Firewall only from trusted private LAN subnets or VPN peers; keep the firewall rule disabled until pairing is complete and remove temporary pairing-port rules immediately afterward.

4. Verify the mesh

.\target\debug\mesh-cli.exe --registry CONTROLLER_HOST:7443 --identity .mesh\cli list --json

The result lists online hosts, their capabilities, and attached devices. A remote job can then target a specific host_id, device_id, and isolated workspace:

.\target\debug\mesh-cli.exe --registry CONTROLLER_HOST:7443 --identity .mesh\cli run --json-request '{"principal_id":"developer-1","host_id":"MAC_AGENT_ID","device_id":"IPHONE_DEVICE_ID","workspace_id":"demo","request_id":"demo-1","manifest":[{"path":"README.txt","contents":"hello from DeviceLane"}]}'

macOS operations

The macOS installer supports repeatable lifecycle commands:

sh ./scripts/setup-mac.sh --controller CONTROLLER_HOST             # install or repair
sh ./scripts/setup-mac.sh --controller CONTROLLER_HOST --status    # inspect service
sh ./scripts/setup-mac.sh --controller CONTROLLER_HOST --upgrade   # rebuild and upgrade
sh ./scripts/setup-mac.sh --controller CONTROLLER_HOST --uninstall # remove installed binaries/service

The unified devicelane client exposes the dashboard over authenticated local IPC. Commands include mesh status|watch, activities list|watch|cancel, approvals list|request|decide, policy list|put|delete, and audit list|export. Every daemon request requires --local; --json returns stable JSON and activity watch returns NDJSON. Events are acknowledged only after stdout accepts and flushes them. Administrative changes use typed approval and access flags; raw shell commands and raw IPC JSON are not accepted.

The per-user DeviceLane daemon has an independent lifecycle and keeps its identity and logs when uninstalled:

sh ./scripts/setup-mac.sh --install
sh ./scripts/setup-mac.sh --status
sh ./scripts/setup-mac.sh --autostart-disable
sh ./scripts/setup-mac.sh --autostart-enable
sh ./scripts/setup-mac.sh --logs
sh ./scripts/setup-mac.sh --uninstall

On Linux the equivalent commands use scripts/setup-linux.sh. The adapter installs a hardened systemd --user unit. Where a user systemd session is unavailable, the script prints the exact devicelane-service --foreground command for a session supervisor or terminal.

On Windows use setup-windows.ps1 with --service-install, --service-repair, --service-status, --service-autostart-enable, --service-autostart-disable, --service-logs, or --service-uninstall. All three adapters use per-user state and log directories.

Diagnostics are written below ~/Library/Logs/DeviceDevelopmentMesh/diagnostics. Identity and trust material remain below ~/Library/Application Support/DeviceDevelopmentMesh and must never be shared.

Security model

DeviceLane grants remote development capabilities and must be treated like privileged infrastructure.

  • Pairing is explicit and creates local cryptographic identities.
  • Normal traffic uses mutual TLS; an unpaired peer is rejected.
  • Pairing listeners are temporary and should be firewall-scoped to one source host.
  • The registry can restrict the exact agent peer IDs allowed to connect.
  • Jobs are confined to declared workspace roots and validated manifests.
  • Device leases serialize writers across clients.
  • Sensitive runtime state lives under .mesh/, which is ignored by Git.

Recommended deployment:

  1. Use a trusted LAN or a private VPN such as WireGuard/Tailscale.
  2. Never forward registry or pairing ports directly from the public internet.
  3. Keep signing keys, Apple credentials, device identities, .mesh/, and diagnostic bundles out of Git.
  4. Restrict host firewalls to known client and agent addresses.
  5. Review audit records and rotate identities after suspected compromise.

See SECURITY.md for vulnerability reporting and operational guidance.

Development and verification

cargo test --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo fmt --all -- --check

Apple bootstrap smoke test (macOS or a compatible POSIX environment):

sh ./scripts/mac-bootstrap-smoke

Physical-device results are deliberately separate from mock, simulator, and fixture tests. Mocks gelten nicht als Nachweis for either hardware gate. A hardware gate is only green after installation, launch, logs, and artifact return succeed on a real authorized device.

DeviceLane dashboard release gate

The dashboard execution worker exposes typed terminal reasons instead of free-form remote errors. Failures preserve the approved activity ID across live events and audit records. If durable audit storage fails, DeviceLane terminates the visible activity with audit_unavailable, marks audit health unavailable, and rejects subsequent auditable mutations until the service has recovered the store. Registry event resync remains distinct from transport reconnect, and daemon restart recovery terminates interrupted work without inventing a replacement activity.

Windows-origin approval requests use the separately paired Windows identity and the registry mTLS path. Invoke devicelane approvals request --local --json with --mesh-registry and --mesh-identity, and omit --principal-id and --source-host-id. DeviceLane derives the Windows SID with the native OS token API and the source host from the certificate identity, signs the exact access request, and accepts the target approval only after the registry and target verify the full signature chain. Free or mismatched remote principal/source values fail with mesh_identity_mismatch before an approval is created.

The normal CI matrix runs the locked Rust workspace, the Tauri bridge, the React dashboard tests, type checking, production frontend build, and lifecycle contract/smoke checks on Windows, macOS, and Linux. That deterministic fixture coverage does not prove a physical Mac pass. A production release additionally requires a real paired Windows-to-Mac run against the target Apple Silicon Mac supplied as <MAC_HOST> at execution time; private LAN addresses do not belong in committed release evidence.

Start the gate on the Mac before submitting the matching operation from Windows. The expected operation must request both workspace_read and device_lease, be approved on the Mac, survive a disconnect/reconnect plus an explicit cursor resynchronization, and reach a terminal state. The script requires Darwin arm64, an authenticated trusted controller session, and the exact binary, SHA-256, and version from the approved build manifest. It refuses fixture mode and writes exactly one generated allow-listed JSON file containing only redacted metadata. Identifiers and the controller address are SHA-256 pseudonyms; raw logs, xcresults, screenshots, audit databases, identities, and secrets are never copied or archived by the mesh gate.

Create a fresh challenge on the Mac (SESSION_CHALLENGE=$(openssl rand -hex 32)). On the paired Windows controller, issue a short-lived assertion with the approved binary and its existing paired identity; DeviceLane derives the principal from the Windows SID and the source host from the certificate identity, so neither value is accepted as operator input:

devicelane controller-session issue --json `
  --identity C:\ProgramData\DeviceLane\identity `
  --mesh-controller "<WINDOWS_CONTROLLER_HOST>:7443" `
  --challenge "<SESSION_CHALLENGE>" > controller-session.json

Copy only controller-session.json to the Mac over the already authorized channel, then run:

DEVICELANE_REAL_MESH_GATE=1 sh ./scripts/mac-hardware-gate.sh \
  --mesh-controller "<WINDOWS_CONTROLLER_HOST>:7443" \
  --controller-peer-id windows-controller \
  --mesh-endpoint "$TMPDIR/devicelane/devicelane.sock" \
  --mesh-identity "$HOME/Library/Application Support/DeviceLane/identity" \
  --controller-session-assertion "$HOME/controller-session.json" \
  --controller-session-challenge "$SESSION_CHALLENGE" \
  --mesh-activity-id release-gate-20260902 \
  --devicelane-binary /absolute/path/to/devicelane \
  --devicelane-sha256 "<APPROVED_LOWERCASE_SHA256>" \
  --devicelane-version "devicelane 0.1.0"

The mesh gate is green only when it observes the Windows principal/source in a target-local approval, live activity through the CLI stream, explicit nonzero-or-unavailable metrics, both a real reconnecting transition and resync_required recovery through a fresh snapshot and replacement epoch/cursor, a terminal result, and exact canonical audit equality. Evidence contains only the canonical audit digest and redacted allow-listed metadata. If the authenticated DeviceLane session is unavailable, report the physical gate as blocked; never replace it with TCP reachability or a fixture pass.

For Yoke-managed work, passes: true is valid only when the mapped story-spezifische Akzeptanzprüfung also passes. The global quality gate additionally runs the complete workspace tests, Clippy with warnings denied, and the formatting check.

Repository map

Path Purpose
src/bin/mesh-registry.rs Registry/control-plane executable
src/bin/mesh-agent.rs Remote host and device agent
src/bin/mesh-cli.rs Client CLI
src/lib.rs Protocol, transport, policy, device, job, and artifact implementation
scripts/ Windows/macOS bootstrap and hardware gates
hardware/DeviceMeshGate/ Minimal signed iOS hardware-gate application
tests/ Contract, security, integration, and platform tests
.yoke/ Yoke planning and acceptance-test metadata
.agents/skills/ Yoke/gstack-derived development-agent workflow skills

Machine-readable project facts

project: DeviceLane
repository: https://github.com/HECer/devicelane
license: MIT
language: Rust
edition: "2024"
binaries:
  - mesh-registry
  - mesh-agent
  - mesh-cli
roles:
  registry: control plane, peer admission, routing, leases
  agent: host capabilities, device adapters, job execution, artifacts
  cli: pairing, discovery, diagnostics, job submission
platforms:
  controller: [windows, macos, linux]
  agent: [windows, macos, linux]
  mobile_targets: [ios, android]
transport: mutual TLS after explicit pairing
default_ports:
  registry: 7443
  cli_pairing: 7444
  agent_pairing: 7445
internet_exposure_supported: false
release_status: experimental
hardware_gates:
  physical_iphone: pending
  physical_android: pending
  windows_to_mac_dashboard: pending

License and acknowledgements

DeviceLane is available under the MIT License. Development workflow material derived from gstack and Yoke remains MIT-licensed; see NOTICE.

About

Secure cross-platform development mesh for remote iOS, Android, macOS, Windows, and Linux device workflows.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages