GasApp

What is encrypted in GasApp — and what is not

Version: 2026-10-10. A map for users, reviewers and auditors: every kind of data GasApp handles, who can read it, and where the code is. It is also the factual basis for the store questionnaires (Data safety, App Privacy, export compliance).

⚠️ GasApp has not had an independent security audit. Every row below can be checked against the source code named in it.

In one paragraph

Private messages, attachments, buttons and reactions in chats are end-to-end encrypted between devices; the server relays ciphertext it cannot read. Channel content is encrypted with a channel key the server does not have — unless the owner makes the channel public, which hands the server the key. Everything on the device is in an encrypted database. All traffic is TLS 1.3 with a pinned certificate, inside Tor when the user turns it on. The server knows account names, a hash of the e-mail address, who subscribes to which channel, and timing — the full list is at the end.

Data in transit

LinkProtectionCode
App ↔ serverTLS 1.3 only (1.2 refused), certificate pinning, no cleartext traffic allowed by the manifestserver/gasapp-server-api/src/tls.rs, android/.../network_security_config.xml
App ↔ networkDirect TLS by default; Tor as a user option (embedded Arti, onion service of the server when configured). With no stored choice the core falls back to Tor, not to a direct connectioncrates/gasapp-tor
Every authenticated requestSigned by the device key over method, path, time and body hash; stale or altered requests are refusedcrates/gasapp-net/src/auth.rs, server/gasapp-server-api/src/authz.rs
Bot engine ↔ serverTLS 1.3 with public-CA validation; no Tor, no pinningcrates/gasapp-bot/src/http.rs

Private conversations (end-to-end)

DataWho can read itHowCode
Message text, replies, edits, deletionsThe two devicesPQXDH key agreement (X25519 + ML-KEM-1024), Double Ratchet, AES-256-GCMcrates/gasapp-protocol/src/pqxdh.rs, double_ratchet.rs
Attachments (photos, files, voice)The two devicesRandom per-file key, XChaCha20-Poly1305 in chunks, size padded; the key travels inside the encrypted messagecrates/gasapp-media/src/attachment.rs
Buttons under a message and button pressesThe two devicesOrdinary message content kinds inside the same sessioncrates/gasapp-protocol/src/keyboard.rs
Who sent a messageRecipient onlySealed sender: the envelope hides the sender from the server (X25519 + ML-KEM-1024)crates/gasapp-protocol/src/sealed_sender.rs
Message sizeHidden to padding bucketsPadding before encryptioncrates/gasapp-protocol/src/padding.rs

What the server stores for a conversation: an opaque envelope until it is delivered (30 days at most), then nothing.

Not covered. Post-quantum protection applies to session setup only, not to the ratchet. A key that only the server named is not trusted for sending: it must be confirmed by a contact link/QR, a safety-number check, or the key-transparency log.

Channels

DataWho can read itHowCode
Title, description, avatar, posts, filesAnyone holding the channel keyAES-256-GCM under a key derived from the channel secret; every record signed by the owner or an administrator (Ed25519)crates/gasapp-protocol/src/channel.rs
Channel key of a link channelWhoever has the linkThe link carries the secret; it never reaches the serversame
Channel key of a public channel (@name)Whoever has the link and the serverThe owner hands the link to the server so the channel can be found by namesame
Channel key of a closed channelApproved members onlySealed to each member's one-time hybrid key (X25519 + ML-KEM-1024 → HKDF → AES-256-GCM): stored grants cannot be opened later by breaking one curve. A new key after every removal of a subscriber or administratorcrates/gasapp-protocol/src/channel_join.rs
A report about a channelThe operatorSent over TLS; the channel key is attached only if the reporter chooses tocrates/gasapp-core/src/client/channel_closed.rs

Not covered. A channel is not a private conversation: no forward secrecy; everyone with the key reads everything published under it. Subscriber counts, views and reactions are server statistics, not signed.

On the device

DataProtectionCode
Messages, contacts, keys, channel keysSQLCipher database; its key is wrapped by a hardware-backed key (Android Keystore) and unlocked by the PINcrates/gasapp-storage, crates/gasapp-keystore
App lock6-digit PIN with Argon2id and attempt limitscrates/gasapp-core/src/lock.rs
Vault for filesSecond factor, separate keycrates/gasapp-core/src/vault.rs
Screenshots, recent-apps previewBlocked by defaultandroid/.../core/SecureWindow.kt
System backupsDisabled (allowBackup=false, extraction rules exclude everything)AndroidManifest.xml
Backup file you createZero-knowledge: Argon2id from a 256-bit recovery key, XChaCha20-Poly1305; without the key it is noisecrates/gasapp-backup

On the server

DataStored asUntil
Username, account and device identifiers, public keysPlainAccount deletion
E-mail addressNot stored. A keyed hash (HMAC-SHA-256) onlyAccount deletion
Undelivered envelopes and attachmentsCiphertextDelivery, 30 days at most
Channel records and filesCiphertext (readable by the server only for public channels)Deletion by the author or with the channel
Who subscribes to which channel, read position, reactionsPlainUnsubscribe or deletion
Join requests and key grants of closed channelsPublic keys and ciphertextAnswer / removal
ReportsReporter, reported account or channel, reason; for chats — a server-signed sender certificate, never the conversationOperator decision
IP addressesNot logged—

Details and retention periods: the data retention policy (docs/legal/data-retention-policy.md).

What is deliberately not encrypted end-to-end

Algorithms

Standard, published algorithms only — no proprietary cryptography:

X25519, Ed25519/XEdDSA, ML-KEM-1024 (FIPS 203), ML-DSA-65 (FIPS 204), AES-256-GCM, XChaCha20-Poly1305, SHA-256, SHA-512, HMAC-SHA-256, HKDF-SHA-256, Argon2id, TLS 1.3.

Protocol specification: docs/protocol/GASAPP-PROTOCOL-v1.md.