Security and privacy
This page explains how shenas stores your data, what leaves your device and under what conditions, how keys are managed, and what shenas does and does not protect against. These are technical claims, not marketing copy. Client-side claims are verifiable in the open-source code; server-side behavior can be verified by inspecting network traffic.
Read the source →Where your data lives
Raw personal data is never uploaded to shenas servers. It lives in a DuckDB database on your own device, under your own filesystem.
Device-local DuckDB files
shenas stores data in two DuckDB files per device. A
device-wide registry at ~/.shenas/data/shenas.duckdb
holds user accounts, sessions, plugin install state, and system
settings. A separate per-user database holds your personal data
(health metrics, finance records, journal entries, and everything
else synced by your sources).
Both files live under your home directory. They are never uploaded to shenas servers. shenas.ai does not operate a database of your personal records (health, finance, journal, or source data). The coordination server holds device identities and relay metadata — not records.
Encryption at rest
Both databases are encrypted on disk using DuckDB's built-in AES-256-GCM encryption. The encryption key is applied at the database attachment step, so plaintext records are not written to durable on-disk storage.
The device-wide encryption key is stored in your operating
system's native secret store: macOS Keychain on macOS, Windows
Data Protection API (DPAPI) on Windows, and the Secret Service
(libsecret) on Linux. Headless and CI environments may use the
SHENAS_DB_KEY environment variable instead; in
that mode, the key is not keyring-backed. Your per-user data
database is encrypted with a key derived from your local
password using
scrypt
(N=16384, r=8, p=1). shenas does not hold copies of either key.
No cloud copy of your records
There is no background upload of your source data to shenas infrastructure. The coordination server used for device sync and federated learning does not receive, store, or process your raw records. If a shenas server were breached, the attacker would find no personal health, finance, or lifestyle data belonging to any user. The servers do hold device-identity metadata (device public keys, device names, relay-message metadata); see the compelled-disclosure item in the threat model for what that means under lawful process.
What crosses the wire
This is the complete list of network calls the shenas application makes. The first three are part of normal use; the rest only happen when you take a specific action or enable an optional feature. No personal records are sent to shenas servers in any of these calls.
On first run, your device generates an Ed25519 keypair. The public key and a device name are sent to the coordination server to enable peer-to-peer sync discovery. The device name defaults to a randomly-generated, non-identifying name (for example, "calm-ridge-47"). You can rename your device at any time from mesh settings. The private key is stored locally and never transmitted.
When you add a second device, new data events from one device
are relayed to the other through the coordination server. The
relay sees only an opaque encrypted payload: it knows which
device sent a message and which device should receive it, but
cannot read the contents. Messages are deleted from the relay
after the recipient downloads them. Undelivered messages are
deleted after 30 days; the server enforces this on every
relay write and poll. Devices on the same LAN connect
directly over UDP and skip the relay. For peers on separate
networks the app performs NAT traversal by sending a STUN
binding request to a public STUN server (currently
stun.l.google.com) to learn its own externally
visible address; that address is published to the
coordination server alongside the device's LAN endpoints so
peers can attempt a direct connection before falling back to
the encrypted relay. See "How it works" for the discovery
flow.
Federated learning is not yet available in this release; the description below covers what will happen when it ships and you opt in. If you opt in to federated learning, your device trains a model locally on your data using PyTorch. After training, the updated model weights (not your records) are transmitted to the coordination server. The server aggregates weights from all participants using secure aggregation (SecAgg+) and differential privacy (DP-SGD) before producing an updated model. The server never receives individual user records.
If you install a source plugin and configure it (for example, a fitness tracker, a calendar, or a code host), shenas contacts that service's API directly from your device, using the credentials you provided, to fetch your data. Token refreshes happen automatically against the same OAuth endpoints during background sync. No data transits through shenas servers — the source and your device talk directly.
If you use the LLM analysis or literature review features with a shenas.ai account, category-level queries (for example, topic names like "sleep" or "stress") are sent to shenas.ai. No personal records are transmitted. These features are off by default and only run when you ask for them; running shenas without a shenas.ai account skips them entirely.
When you install a plugin, shenas downloads a signed wheel
from repo.shenas.net and its Python dependencies
from pypi.org. The signature is verified before
install. No personal data is transmitted — the only thing
either server learns is which packages you asked for.
If you run shenasctl model download to install a
local AI model, the GGUF model file is fetched from
HuggingFace. No personal data is sent — the request is just
for the file. Once downloaded, the model runs entirely on
your device.
Single-device installs
If you run shenas on one device only and do not participate in federated learning, the shenas application contacts these external servers during normal use:
- The coordination server (account auth, device registration, endpoint refresh, and relay polling — even without a second device, the relay is polled; nothing is relayed without a paired device to receive it).
- The third-party API of each connected data source when its scheduler is due (for example, the API endpoint of a fitness tracker you connected). These calls go directly from your device to the source; no data routes through shenas servers.
These additional servers are contacted only when you take a specific action: shenas.ai for an LLM or literature-findings query you triggered; repo.shenas.net and pypi.org when you install a plugin; huggingface.co when you download a local AI model. Your configured LLM provider — a local Ollama server or a third-party API — is also contacted only when you run an LLM-assisted analysis, and that call goes to the provider you chose, not to shenas.
Local sync logic and analysis run entirely on your device.
Key management
shenas does not hold encryption keys for user data. There is no key escrow, no recovery service, and no server-side copy of any key material.
Database encryption keys
The device-wide database key is generated once on first run, stored in the OS keyring, and never transmitted. The per-user database key is derived on login from your local password via scrypt; it exists in memory only while you are logged in, unless you enable background sync, in which case a copy of the derived key is stored in the OS keyring to allow background data refresh. shenas has no mechanism to recover this key.
Device identity keys
Each device holds an Ed25519 private key used to authenticate to the sync coordination server. This key is generated locally, stored in the device's encrypted database, and never transmitted. The coordination server stores only the corresponding public key.
What device loss means
If you lose a device, the data on that device is protected by OS-keyring-backed encryption. An attacker who obtains the device cannot read the database without first gaining access to the OS keyring (which typically requires your login credentials or biometric authentication). A secondary device that was syncing with the lost device retains its own local copy of the data.
shenas cannot restore data from a device you no longer have. There is no cloud backup of your personal records. This is a deliberate property of the architecture, not a missing feature.
Threat model
What shenas protects against, and what it does not claim to protect against. Honest security documentation names both.
What shenas protects against
- Server-side breach. A compromise of shenas infrastructure would expose no user data records. The servers hold only public keys, encrypted relay payloads, and aggregated model weights.
- Network interception. All data in transit is encrypted. Sync relay payloads are opaque to the relay server. Federated learning gradients are protected by secure aggregation before the server sees individual contributions.
- Unattended device access. Databases are encrypted at rest with AES-256-GCM. Reading the database files without the OS keyring key or user password is not feasible with current hardware.
- Supply-chain compromise via plugins. Every plugin distributed through the official package repository is signed with an Ed25519 key. The CLI verifies the signature before installation. A tampered plugin will not install.
- Compelled disclosure to shenas of your records. shenas does not hold the contents of your records, so a subpoena or court order served on shenas the company for those contents has no records to produce. We can still be compelled, under lawful process, to disclose the metadata we hold (device public keys, device names, and relay-message metadata such as sender, recipient, and timing — never message contents), and to disclose the existence of process where the law requires us to do so.
What shenas does not protect against
- A local attacker with both device access and your credentials. If someone has your unlocked device and your local shenas password, they can read your data. The database encryption assumes the attacker cannot authenticate to the OS or guess your password.
- OS-level or hypervisor-level compromise. If the operating system itself is compromised (malware with root access, a malicious hypervisor), all bets are off regardless of application-level encryption.
- Compelled self-disclosure by you. shenas cannot protect you from being legally compelled to hand over your own device or decrypt your data. It can only ensure that shenas the company cannot be compelled to hand over what it does not hold.
- Malicious plugins you choose to install from untrusted sources. Plugins have access to your local data by design. Installing an unsigned or third-party plugin from an untrusted source is equivalent to running untrusted software with access to your data directory.
- Source API credentials. OAuth tokens and API keys for external services (a fitness tracker, a language app, etc.) are stored in your local database. A successful attack on your unlocked device could expose these. shenas does not protect against device compromise beyond the encryption at rest.
Telemetry and logging
No transmitted telemetry
shenas does not transmit usage telemetry. The application maintains a local diagnostic log written to your own database for in-app trace and log views; nothing in that log leaves your device. No analytics calls, crash reports, feature-usage beacons, or identifiers are sent to shenas servers in the course of normal use.
You can verify this by running shenas behind a local network
proxy and inspecting outbound traffic. The code is open
source; the relevant paths are
app/mesh/
for sync and registration,
app/fl/
for federated learning, and
app/telemetry/
for the local-only diagnostic exporters.
The network calls shenas makes during normal use — excluding data source sync, plugin install, model download, and optional features you explicitly enable — are the ones described in "What crosses the wire" above.
How to verify these claims
Client-side claims are grounded in code you can read and run. Server-side behavior can be verified by inspecting network traffic.
See app/db.py
for how DuckDB databases are opened with ENCRYPTION_KEY,
and app/database.py
for how keys are loaded from the OS keyring or derived from
user passwords.
See app/mesh/identity.py
for Ed25519 key generation and the information sent during
device registration (public key and device name only).
See app/mesh/relay_sync.py
for how sync events are encrypted before transmission and
how the relay handles opaque payloads.
See the CLI source in
shenasctl/
for how Ed25519 signatures are verified before a plugin wheel
is installed.
Open source
The core platform, sync layer, federated learning client, and CLI are published under an open-source licence at github.com/shenas-org/shenas. The server-side coordination and aggregation code (federated learning coordinator, sync relay) is not currently open source. Claims about server behavior can be verified by inspecting network traffic rather than server source.
Security disclosures
Reporting a vulnerability
If you find a security issue in shenas, please report it privately. Do not open a public GitHub issue for unpatched vulnerabilities. Use GitHub's private security advisory feature at github.com/shenas-org/shenas/security/advisories/new or email [email protected].
We aim to acknowledge reports within two business days and to publish a fix or mitigation within 90 days of confirmation.