Home/ Knowledge Base/ Projects & the .relay archive/ Secrets & encryption
Projects & the .relay archive

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.json stores 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

A lost passphrase cannot be recovered. It's never written anywhere — it only exists in the moment you type it to derive the key. If you lose it, the secrets in that archive can't be decrypted by anyone, including us. Keep it in a password manager.

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 .relay one way and the passphrase another.
  • Don't put secrets in support tickets. We never need them; see Security & privacy.

Next steps