Skip to content

Security

Jarvis is designed with privacy and security as core principles. All data stays on your network by default, with no cloud dependencies required.

Zero-Trust Architecture

Jarvis follows a zero-trust security model --- no service, node, or client is implicitly trusted, regardless of network location. Every request is authenticated and verified independently at every boundary.

Most self-hosted assistants rely on "it's on my LAN, so it's fine." Jarvis does not. Even services running on the same Docker network authenticate to each other on every call.

How this manifests in practice:

Principle Implementation
Verify explicitly Every service-to-service call carries X-Jarvis-App-Id + X-Jarvis-App-Key headers. The receiving service validates them against jarvis-auth --- it never assumes the caller is legitimate.
Never trust the caller The command center does not cache "this node is trusted." Every node request is validated with the auth service via the X-API-Key header.
Encrypt at rest Node secrets (API keys, OAuth tokens) are stored in AES-256 encrypted SQLite (pysqlcipher3). The encryption key (K1) never leaves the device.
Encrypt in transit Settings sync between mobile and node is end-to-end encrypted with AES-256-GCM (K2 key). The command center transports the encrypted blob but cannot read it.
Least privilege Nodes are scoped to a household. App-to-app keys are scoped per service. Admin endpoints require a separate ADMIN_API_KEY.
Assume breach Even if the Docker network is compromised, an attacker cannot impersonate a service without valid app credentials, or read node secrets without the device's K1 key.
graph LR
    Node -->|"X-API-Key (every request)"| CC["Command Center"]
    CC -->|"X-Jarvis-App-Id + Key"| Auth["Auth Service"]
    CC -->|"X-Jarvis-App-Id + Key"| LLM["LLM Proxy"]
    CC -->|"X-Jarvis-App-Id + Key"| Logs["Logs Service"]
    Mobile -->|"Bearer JWT"| CC
    Mobile -.->|"E2E encrypted (K2)"| Node

    style Node fill:#4a148c,color:#fff
    style CC fill:#4a148c,color:#fff
    style Auth fill:#4a148c,color:#fff
    style LLM fill:#4a148c,color:#fff
    style Logs fill:#4a148c,color:#fff
    style Mobile fill:#4a148c,color:#fff

Roadmap items

Two items will strengthen the zero-trust posture further: mTLS between services (Phase 2 on the compliance roadmap) and RBAC with per-request authorization scoping (Phase 4). The trust boundaries are already in place --- these additions add defense-in-depth.

Authentication Patterns

Jarvis uses three authentication patterns depending on who is communicating:

1. Node Authentication

Pi Zero nodes authenticate to backend services using an API key:

X-API-Key: {node_id}:{api_key}

The receiving service validates the key against jarvis-auth. Node credentials are created during provisioning and stored in the node's encrypted local database.

2. App-to-App Authentication

Backend services authenticate to each other using service credentials:

X-Jarvis-App-Id: <app_id>
X-Jarvis-App-Key: <app_key>

App credentials are generated by ./jarvis init and stored in each service's .env file. Services validate incoming app-to-app requests against jarvis-auth via POST /internal/validate-app.

3. User Authentication (JWT)

Human users (mobile app, admin UI) authenticate with JWT bearer tokens:

Authorization: Bearer <jwt_access_token>

JWTs are issued by jarvis-auth on login, signed with HS256 using a shared secret key. Access tokens are short-lived; refresh tokens are hashed and stored in PostgreSQL.

Encrypted Local Storage

Pi Zero nodes store secrets (API keys, OAuth tokens, command credentials) in a local SQLite database encrypted with PySQLCipher. The encryption key (K1) is generated on first boot.

Settings sync between the mobile app and nodes uses a shared AES-256 key (K2), exchanged during provisioning.

No Cloud Dependencies

By default, Jarvis runs entirely on your local network:

  • Speech-to-text runs locally via whisper.cpp
  • LLM inference runs locally via MLX (macOS) or llama.cpp (Linux)
  • Text-to-speech runs locally via Piper TTS
  • All data is stored in your PostgreSQL instance
  • No telemetry, no external API calls (unless you configure them)

Credential Rotation

App-to-app credentials can be regenerated by running ./jarvis init --force, which generates new tokens and updates all service .env files. Node credentials can be rotated by re-registering the node.

Multi-Tenant Isolation

All data is scoped by household_id. Users can only access data within their household. Nodes belong to a household and can only submit commands for that household's users.

Compliance Roadmap

For B2B deployments (hospitals, law firms, enterprises), Jarvis has a phased security roadmap targeting HIPAA, SOC2 Type II, HITRUST CSF, FedRAMP, ISO 27001, and PCI DSS compliance.

See the Compliance Roadmap for details.