My AI Assistant: Building a Private, E2EE Mobile Command Center with Signal, Obsidian, and Antigravity CLI (agy)

By | August 16, 2026

In modern self-hosting and homelab architecture, remote management often forces a trade-off between convenience and security. Exposing web interfaces to the public internet or relying on proprietary cloud bots introduces security vectors and metadata leakage.

By combining Signal (the gold standard of end-to-end encrypted messaging), Antigravity CLI (agy) (an autonomous local AI agentic assistant), and Obsidian (a local-first knowledge base), I built “My AI Assistant”—a zero-cloud, E2EE mobile command center. From anywhere in the world, a simple Signal message to my “Note to Self” or private bot can query homelab NAS servers, control IoT smart home devices, run hardware diagnostics, and capture research directly into my personal Obsidian vault.

🏗️ System Architecture

The setup relies on a local daemon running on my primary workstation/laptop, listening to Signal messages over JSON-RPC, invoking agy in non-interactive print mode, and executing local shell scripts or system tools.

🔑 Core Components

1. Signal (signal-cli) — End-to-End Encrypted Transport

  • Zero Metadata Leakage: Unlike proprietary messengers, Signal collects zero interaction metadata.
  • Linked Device Mode: signal-cli connects as a linked secondary device under my primary Signal account using standard Signal Protocol keys (Double Ratchet Algorithm, Curve25519, AES-256-GCM).

2. Antigravity CLI (agy) — Autonomous Agentic Engine

  • Non-Interactive Execution: agy runs with --dangerously-skip-permissions and --print-timeout 10m to execute system tools, SSH commands, script queries, and file modifications without pausing for manual terminal input.
  • Local Context Awareness: Accesses local CLI script libraries (/home/gvoina/scripts/), SSH keys, and system states.

3. Obsidian Vault (/home/gvoina/Vault/George/) — Local PKM & Knowledge Capture

  • Markdown-native personal knowledge management vault stored locally on disk.

🛡️ THE 3-LAYER SECURITY ARCHITECTURE

Preventing Number Spoofing, Cross-Chat Leaks & Unauthorized Access

Exposing an AI assistant with shell access to a chat interface requires zero-trust security design. When using signal-cli, the daemon receives all synchronized messages (syncMessage) from your phone, including chats sent to third parties or incoming messages from external contacts.

To eliminate all attack vectors, the daemon enforces a 3-Layer Security Model:

Layer 1: Cryptographic Identity & Anti-Spoofing

Why Signal is Immune to Caller-ID Spoofing
  • SMS vs. Signal Cryptography: On traditional telephony networks (SMS or voice calls), caller-IDs can be easily fake-spoofed because legacy telecommunications infrastructure (SS7) lacks cryptographic sender verification. Signal does not use SS7 or phone network headers.
  • Hardware-Backed Keypairs (Curve25519): Every Signal account is bound to an End-to-End Cryptographic Identity Keypair generated inside the mobile phone’s secure hardware enclave.
  • Asymmetric Digital Signatures: Every message payload sent over Signal is digitally signed with the sender’s private key. Signal relay servers and signal-cli mathematically verify the digital signature of every incoming packet. An attacker cannot fake or forge your phone number without physically possessing the private encryption keys stored inside your mobile phone hardware.

Layer 2: “Note to Self” Destination Scoping

  • Cross-Chat Isolation: When texting friends, family, or work groups on Signal, outgoing syncMessage payloads carry an external destinationNumber.
  • Destination Guard: The daemon checks destinationNumber == ALLOWED_ACCOUNT. Any message sent to external contacts or group chats is immediately dropped and logged:if msg and (dest == ALLOWED_ACCOUNT or dest is None): threading.Thread(target=process_message, args=(ALLOWED_ACCOUNT, msg)).start() else: print(f"SECURITY GUARD: Ignored message sent to external contact {dest}")
  • External User Blocking: Direct incoming messages from third-party senders (source != ALLOWED_ACCOUNT) are automatically blocked.

Layer 3: Hardcoded Target Response Routing

  • Hardcoded Target: The AI reply destination is hardcoded directly in the Python process dispatch:send_cmd = ["signal-cli", "-u", ALLOWED_ACCOUNT, "send", "-m", reply, ALLOWED_ACCOUNT] subprocess.run(send_cmd)
  • Guaranteed Isolation: AI output responses can never be misdirected to any external contact or group chat.

🛠️ How It Works Under the Hood

The background service signal-bot.service runs as a systemd user daemon:

[Unit]
Description=Signal AI Assistant Bot Daemon
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/gvoina/scripts/signal_bot.py
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

🌟 Real-World Use Cases: What I Can Do From My Phone

🧠 1. Obsidian Knowledge Capture & Research

From my phone, I can text articles, notes, or ideas directly into my personal Obsidian vault:

  • Web Summaries & Link Archiving: “Save link https://example.com/research-paper to my Obsidian vault under Resources with a summary and tags.”🤖 Result: agy fetches the webpage, extracts key insights, formats YAML frontmatter, and creates Research-Paper.md directly inside /home/gvoina/Vault/George/Resources/.
  • Quick Inbox Capture: “Add to Obsidian Inbox: Ideas for expanding NAS storage using 2.5-inch to 3.5-inch drive adapters.”
  • Automated Project Notes: “Create a new note in Obsidian titled ‘Network Redundancy’ detailing our EdgeRouter 6P console setup on /dev/ttyUSB0.”

🏠 2. IoT & Smart Home Management

Control and query my smart home environment remotely through Home Assistant integration scripts:

  • Climate & Environment Queries: “What is the current office CO2 concentration and bedroom temperature?”🤖 Response: Queries sensor.office_zorilor_office_zorilor_co2_concentration (485 ppm) and sensor.bedroom_zorilor_temperature (22.4 °C) via Home Assistant API scripts.
  • Motorized Blinds & Covers Control: “Close the living room blinds to reduce heat.”🤖 Response: Proposes and executes /home/gvoina/scripts/control_ha_cover.sh cover.living_fix_1 close.
  • HVAC & AC Unit Adjustment: “Set office Daikin AC to 21°C.”

🖥️ 3. Homelab & NAS Infrastructure Diagnostics

Monitor hardware integrity, RAID arrays, disk SMART health, and UPS power metrics across multiple NAS servers (nas1, nas2, nas3):

  • Comprehensive Drive Health & RAID Audit: “Check disk status on nas3.”🤖 Response: Audits SMART attributes on /dev/sda through /dev/sdj. Reports that the 4.5TB WD Red RAID 1 array (/mnt/wd_red_raid) is 100% active with 4.3 TB free, alerts if any drive (e.g. WD-WX31A4309831) shows reallocated sector failures, and confirms clean unmounts.
  • Power & Network UPS Telemetry: “Check UPS status across nas1 and nas3.”🤖 Response: Queries local volt_ups (127.0.0.1:3493) and remote rack_ups_2 (127.0.0.1:34930), reporting battery.charge: 100% and battery.voltage: 27.29V.
  • Serial Console & Network Infrastructure: “Is the EdgeRouter serial console adapter ready?”🤖 Response: Confirms Prolific PL2303 USB-to-Serial adapter is active at /dev/ttyUSB0 (115,200 baud).

💳 4. Financial & Off-Grid Operations

  • Wise Wallet Balances & Encrypted Transfers: “Query my Wise wallet balances.”🤖 Response: Executes wise_wallet.py balance with RSA 2FA signing.
  • Meshtastic (LoRa) Off-Grid Fallback: If cellular and internet networks fail, the system seamlessly falls back to local LoRa radio nodes (vg-5ee8vg-2456) on the private channel voina.

🎯 Conclusion

By bridging signal-cli, agy, Obsidian, and Home Assistant with a 3-Layer Security Architecture, my mobile phone becomes a fully autonomous, encrypted command center for My AI Assistant. No central cloud server holds my keys, caller-ID spoofing is mathematically impossible, cross-chat leaks are prevented, and my homelab infrastructure remains strictly under my control.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.