Encrypted Diagnostic Export
Encrypted Diagnostic Export
AfterTouch can produce an encrypted diagnostic report that users can download and
send to the project maintainer without exposing sensitive data to third parties.
The report is encrypted with an SSH public key using
age; only the holder of the matching
private key can read it.
What the report contains
The encrypted .age file decrypts to a .tar.gz archive with:
diagnostic.json— structured summary:- Service version and build info
- Full health-check results (same data as the Health tab)
- Per-device state: sources (IDs, names, SourceKeyTypes), presets (slot, name, Source, SourceID, location), device product code, firmware version, IP, name
datastore/accounts/{id}/devices/{id}/*.xml— raw XML files verbatim from the sender’s datastore (Presets.xml,Sources.xml,Recents.xml, …)
Having both the structured JSON and the raw XML lets you compare what the service serves via HTTP against what is actually stored on disk.
What is excluded from the JSON: authentication tokens, credentials, OAuth secrets, Spotify refresh tokens. The raw XML files are included as-is.
Maintainer setup (one-time)
This section is for the project maintainer only. Users never need to touch keys.
1. Generate the key pair
bash scripts/setup-diagnostic-key.shThis creates:
keys/private/diagnostic— SSH ed25519 private key (gitignored, never commit)keys/private/diagnostic.pub— copy for reference (gitignored)keys/public/diagnostic.pub— public key committed to the repo
2. Add the public key to GitHub
Go to https://github.com/settings/ssh/new and paste the contents of
keys/public/diagnostic.pub. This makes the key visible at
https://github.com/gesellix.keys so users can independently verify that the
key embedded in the binary matches a key actually controlled by the maintainer.
3. Embed the public key in the binary
Open pkg/service/export/encrypt.go and update the DiagnosticPublicKey
constant to match the new public key:
const DiagnosticPublicKey = "ssh-ed25519 AAAA... aftertouch-diagnostic@gesellix"4. Commit
git add keys/public/diagnostic.pub pkg/service/export/encrypt.go
git commit -m "keys: add diagnostic SSH public key"keys/private/ is .gitignored — the private key will not be committed.
5. Back up the private key
The private key is not stored in git. Keep a copy in a secure location
(password manager, encrypted USB drive, etc.). If it is lost, a new key pair
must be generated and the constant in encrypt.go updated.
Verifying the embedded key (users)
Users who want to confirm that the key embedded in their running binary matches the maintainer’s GitHub SSH keys can run:
# Compare the raw key text — both should show the same line:
curl -s https://github.com/gesellix.keys
cat keys/public/diagnostic.pubThe key should appear verbatim in both outputs.
Decrypting a received report (maintainer)
When a user sends you an aftertouch-diagnostic-*.age file, use the helper
script (no extra tools needed — only Go and the private key). Run from the
repository root directory:
# Decrypt and extract in one step:
go run scripts/decrypt-diagnostic.go aftertouch-diagnostic-<timestamp>.age | tar xz
# Or decrypt to a .tar.gz first, then inspect:
go run scripts/decrypt-diagnostic.go aftertouch-diagnostic-<timestamp>.age > report.tar.gz
tar xzf report.tar.gz
# → diagnostic.json
# → datastore/accounts/{id}/devices/{id}/Presets.xml (and Sources.xml, Recents.xml, …)The script uses only the filippo.io/age Go module — no separate age CLI
installation required.
User workflow
- Open the AfterTouch admin UI and go to the Health tab.
- Click Download diagnostic report.
- The browser downloads
aftertouch-diagnostic-<timestamp>.age. - Attach the file to the GitHub issue or send it via a direct channel.
The file is opaque binary — the user cannot read it. All they see is that the report was generated and downloaded.
Key rotation
If the private key is compromised or lost:
- Run
scripts/setup-diagnostic-key.sh(delete the oldkeys/private/diagnosticfirst). - Add the new public key to GitHub and remove the old one.
- Update
DiagnosticPublicKeyinencrypt.go. - Commit and tag a new release.
Old reports encrypted with the previous key cannot be decrypted with the new key.