Not legal advice
This policy has not been reviewed by a solicitor. It is written in plain language and describes what the app actually does. If you need legal advice about data protection, please consult a qualified solicitor.
Short version: meshDeck has no accounts, no analytics, no advertising and no tracking. It connects from your phone straight to your own hosts, and your keys stay in your iPhone’s Keychain. Two features you switch on yourself reach other services: AI diagnosis sends a redacted bundle to the AI provider you choose, and Instant alerts register your phone with a small relay we run so a push notification can reach you. Everything else stays between your phone and the hosts you own.
This policy explains how AG Applications LTD (“we”, “us”, “our”) handles information when you use meshDeck (the “App”). We are the controller of the limited personal data described in sections 6 and 7.
Contents
- What we do not collect
- How the App connects
- What is stored on your device
- What the App writes to your hosts
- AI diagnosis (optional)
- Instant alerts and the relay (optional)
- Tailscale
- Apple
- Third-party components
- Permissions
- Retention and deleting your data
- Children
- Your rights
- Security
- Changes to this policy
- Contact
1. What we do not collect
We do not run an account system, so we do not know who you are. The App has no analytics, no crash-reporting SDK, no advertising and no tracking. It does not read your advertising identifier, and it asks for none of your contacts, photos, location, microphone or camera.
We never receive:
- the names, addresses or contents of your hosts, containers, images, volumes or networks;
- your SSH keys, passwords, Portainer tokens, Tailscale keys, AI keys or vault values;
- your logs, environment variables or compose files;
- your purchase details. Apple handles those.
2. How the App connects
There is no meshDeck server in the path between your phone and your hosts. The App connects directly to:
- your hosts, over SSH (with
docker system dial-stdioor the docker command line) or over HTTPS to your own Portainer, using an access token you create; - your hosts through Tailscale, using a Tailscale node built into the App, when you choose that for a host (section 7).
Host keys and server certificates are pinned the first time you connect, and you are asked before a changed one is accepted. The App never asks you to expose Docker’s API on the internet.
3. What is stored on your device
In the iOS Keychain, for this device only and never synchronised with iCloud Keychain:
- SSH private keys generated by the App or imported by you, and SSH passwords;
- Portainer access tokens and sudo passwords, where you chose to store one;
- vault secrets you added;
- your AI provider key, and a Tailscale auth key if you used that sign-in method;
- if you use Instant alerts: the credentials the relay issued to your phone, an agent token for each enrolled host, and a payload key.
Keychain items are readable while the phone is unlocked, except the small set the notification extension needs, which is readable after the first unlock since a restart so that a notification can be decoded on a locked phone.
In the App’s storage on your phone (not secret, but private to you): your list of hosts (names, addresses, ports, usernames and how you sign in), your saved drafts and systems, the fingerprints of hosts and certificates you have trusted, the names and dates of your vault entries, your settings, and, if you use Instant alerts, the notification token Apple gave your phone. Drafts and systems can contain environment values you typed in plain, so treat them like a compose file.
Backups. If you back up your iPhone, Apple includes that non-secret app data in the backup. Keychain secrets are marked this-device-only, so they are not restored onto a different device. The Tailscale node’s state is excluded from backups.
None of this is sent to us.
4. What the App writes to your hosts
When you deploy a stack, the App writes to your host over your own connection:
- the compose file, in
~/.meshdeck/stacks/<name>/; - a
.envfile with the stack’s environment, including the value of any vault secret you bound to it, created with mode 600 (readable only by your user); - for a private Git repository, a credentials file (also mode 600) holding the username and token you typed. The App does not keep that token after the deploy.
If you deploy through Portainer, the compose file and environment are sent to your Portainer server, which stores them under its own rules.
A vault value reaches a host only at deploy time, and only the host you deploy to. Drafts, templates and screenshots hold a reference to the vault entry, not the value. What is on your hosts, and who can read it, is governed by your own security practices there.
5. AI diagnosis (optional)
AI diagnosis is off until you add your own API key for a provider you choose (Anthropic, or any OpenAI-compatible server, including one you run yourself) and agree that container data may be sent to it. It never runs by itself: one request is sent each time you tap “What’s wrong?”.
What is sent, from your phone straight to the provider you chose:
- the host’s display name and the container’s name, image, status, health, exit code, restart count and start and finish times;
- the container’s command and environment, after masking (below);
- up to 200 of the newest log lines, capped at 8 KB, after masking;
- about the last minute of CPU and memory readings;
- the names of the other containers, volumes and networks linked to it, and any broken link;
- the container’s lifecycle events from the last 15 minutes, and the Docker version.
What is not sent: vault values, SSH keys, passwords, tokens, your host’s address, port bindings, mounts, or any other container’s environment or logs. A vault-bound variable is replaced by a placeholder that names the entry, never its value.
Masking has limits. Before anything is sent, the App masks the values of variables whose names look secret (password, token, key, credential and similar), token-shaped strings, credentials in URLs, and the value after a secret command-line flag. If a secret-looking value survives that check, nothing is sent at all. But masking recognises patterns. A secret that looks like ordinary text, for example a random password in a variable with an innocent name, or one printed in a log line, can get through. Values that are not secret at all, such as a hostname or a port, are sent as they are. If that matters to you, leave AI diagnosis off.
What the provider does with it is governed by the provider’s own terms and your account with them. We do not receive a copy and we run no server in the path. If you point the App at an http:// model server, that traffic is not encrypted, so use one on a network you trust.
What comes back is a summary, up to three causes and up to three suggested actions from a fixed list the App already implements. Nothing runs by itself. Every action needs your tap, and there is no shell or command for the model. The result stays in memory and is not saved.
6. Instant alerts and the relay (optional)
Instant alerts are off until you turn them on in Settings. When you do, the App asks iOS for permission to send notifications and registers your phone with a small relay we run at mdrelay.meshterm.com. Apple’s push service delivers the notifications.
At the time of writing the App can enrol a host and send you a test alert. The agent that would watch a host and send real alerts is not yet released, so no other alerts are sent.
What the relay holds, in a file on its server:
- your phone’s Apple push token;
- a random identifier and a hashed secret for your phone (the secret itself stays on your phone), and your per-kind alert preferences;
- for each host you enrol: a random identifier, a hashed agent token, which of your phones are attached to it, and when it last checked in.
What the relay does not hold: host names, container names, addresses, alert text, your name, your email, or any account. Each alert is encrypted on the host with a key that only your phone and that host have, and decrypted on your phone by the App’s notification extension. The relay forwards the encrypted bundle without being able to read it. The words on the banner are composed on your phone.
What the relay can still see. We are honest that “cannot read the alert” is not “knows nothing”. Because of how a relay works, it can see: how many phones and hosts are registered; that a given push token is attached to a given opaque host identifier; each phone’s alert preferences; when a host last checked in and whether it has gone quiet; the time, kind and a stable but meaningless per-container label of each alert; and the network address a request came from while it is being handled. It cannot tell what any host or container is.
Logs. The relay logs only failures, in coalesced form, with no tokens, identifiers, addresses or alert content. Our web server may record network addresses in routine error logs, which the server keeps for no more than a month. We keep aggregate counters (for example, how many alerts were sent) with no per-person detail.
Lawful basis (UK GDPR). Where the relay handles personal data, that is your push token and the identifiers linked to it, we do so to provide the alerts you asked for (performance of a contract with you) and to keep the service secure.
Apple. Apple’s push service receives the encrypted notification and your push token in order to deliver it, under Apple’s privacy policy.
7. Tailscale
If you sign in to Tailscale in the App, or use it to reach a host, the App runs its own Tailscale node on your phone. It talks to Tailscale’s control servers, or to the Headscale server you set, to authenticate and to find your other devices, and to relay traffic if a direct path is not possible. Sign-in happens in a web sheet with Tailscale or your identity provider. We never see your Tailscale credentials or your traffic.
The App tells the control server the device name you chose. Its default is “meshDeck on” followed by your phone’s name, and you can change it. Tailscale’s own privacy policy governs what it does with that. Signing out in the App removes the node’s state and key from your phone. You may also want to remove the device from your Tailscale admin console.
8. Apple
The App is distributed through the Apple App Store. Apple processes your download and, if you subscribe to meshDeck Pro, your payment, through StoreKit. The App learns only whether you have an active subscription. We do not receive your payment details or your Apple Account. If you have chosen to share diagnostics with app developers in iOS Settings, Apple may pass us anonymised crash information. Apple’s privacy policy governs all of this.
9. Third-party components
The App includes open source components that run on your phone and send nothing to us: SwiftNIO, SwiftNIO SSH and SwiftNIO SSL (Apache 2.0), swift-crypto and swift-log (Apache 2.0), SwiftTerm (MIT) and the Tailscale library (BSD-3-Clause). The App contains no advertising network, no social SDK and no analytics.
10. Permissions
- Local Network. So the App can reach hosts on your own network. It only connects to addresses you enter.
- Notifications. Asked only when you turn on Instant alerts.
- Clipboard. Read only when you choose to paste a key, and by a shell program that asks to. The App writes to it only when you press a copy button.
11. Retention and deleting your data
On your phone, everything is yours to remove. Deleting a host removes its stored credentials and its alert enrolment. Deleting the App removes its storage. iOS may keep Keychain items after an app is deleted, so remove secrets you care about in the App first (Settings → Vault, and each host).
On the relay, there is currently no automatic expiry. A record stays until you turn Instant alerts off, remove the host, or Apple tells us your push token is no longer valid, at which point we delete it. Turning alerts off deletes your phone’s record and any host that no longer has a phone attached. If you delete the App without turning alerts off, your record may remain on the relay, and you can ask us to delete it (section 16).
On your hosts, the App only deletes what it created under ~/.meshdeck/stacks/, and only when you remove a stack. It never deletes anything you did not ask it to.
Subscription records are held by Apple. We keep no records of our own about you beyond the relay data above and any correspondence you send us.
12. Children
meshDeck is not directed at children. It is a tool for people who administer servers, and we do not knowingly collect personal data from children.
13. Your rights
Under the UK GDPR and the Data Protection Act 2018 you can ask us for access to the personal data we hold about you, to correct it, to erase it, to restrict or object to how we use it, and to receive it in a portable form. Because almost everything stays on your phone and your hosts, the data we hold is limited to the relay records in section 6 and any correspondence. To exercise a right, contact us (section 16). We will reply within one month.
If you are unhappy with how we have handled your data, you can complain to the UK Information Commissioner’s Office at ico.org.uk. We would like the chance to put it right first.
14. Security
The App stores secrets in the iOS Keychain, connects over SSH and TLS, pins host keys and certificates, and asks before its riskier actions. The relay hashes the secrets it issues, holds as little as it can, and runs with a restricted service profile. It stores your push token as it is, because Apple needs it to deliver a notification; the Security page explains what that means and what we are changing. No system is perfectly secure, and we cannot promise that yours is. More detail is on the Security page.
15. Changes to this policy
We may update this policy. We will change the date at the top and, for a material change, tell you in the App. If you keep using the App after a change takes effect, you accept it. Earlier versions are available on request.
16. Contact
AG Applications LTD, company number 17447911.
Email: james@ag-applications.com
Privacy questions, requests to delete relay records and complaints all come to this address.