Secrets & encryption
How AppRelay stores API keys and signing credentials, how the passphrase-derived AES-GCM encryption works, and why a lost passphrase can’t be recovered.
Last updated 2026-07-02
Building and shipping needs credentials — App Store Connect keys, Android upload keystores, Firebase and deploy tokens. AppRelay treats these as secrets: values you reference by name and that are encrypted whenever they leave the app. This article explains how that works and what it means for you.
References vs. values
Everywhere you'd use a secret — a recipe command, a distribution's parameters — you write a reference, not the value:
xcrun altool --upload-app -f app.ipa --apiKey {secret.ascKey}
The reference ascKey is just a name. The actual value lives in the secret store and is substituted at run time. This keeps secret values out of your recipe text, out of the project manifest, and out of the visible step log.
Encryption in the .relay archive
When you export a .relay archive, the secret values are encrypted into a single blob:
- Key derivation
- Your passphrase is stretched into a 256-bit key with PBKDF2-HMAC-SHA256 using a random 16-byte salt and a high iteration count (310,000+).
- Encryption
- The secrets JSON is sealed with AES-GCM, which is authenticated — it detects tampering as well as protecting confidentiality.
- Metadata
secrets.meta.jsonstores the KDF name, iteration count, salt, and nonce — everything needed to derive the key again from the passphrase, but not the passphrase itself.
The passphrase is never stored
The upside of the same design: a wrong passphrase is detected cleanly. Because AES-GCM is authenticated, a bad key fails the integrity check rather than returning garbage — that failure is exactly AppRelay's “wrong passphrase” signal.
Binary secrets travel too
Some credentials aren't text — an Android keystore, for example. The secrets blob is stored in a way that can carry binary data (base64-capable), so keystores and similar files travel inside the archive alongside token strings.
Good practices
- Reference, never inline. Always use
{secret.<ref>}in recipes; never paste a raw key. - Use a strong, unique passphrase per archive, stored in a password manager.
- Share file and passphrase separately. Send the
.relayone way and the passphrase another. - Don't put secrets in support tickets. We never need them; see Security & privacy.