Skip to content
Documentation GitHub
Development Guides

Release Playbook

Updater Signing Key Management

The Tauri updater plugin uses Ed25519 signatures to verify that updates are authentic. Every release build signs its artifacts with a private key; the public key is embedded in tauri.conf.json so the running app can verify downloads before applying them.

Key Inventory

AssetLocationNotes
Public keyapps/desktop/src-tauri/tauri.conf.jsonplugins.updater.pubkeyCommitted to repo. Base64-encoded minisign public key.
Private key1Password + GitHub Actions secret TAURI_SIGNING_PRIVATE_KEYNever committed. Used only in CI.
Private key password1Password + GitHub Actions secret TAURI_SIGNING_PRIVATE_KEY_PASSWORDNever committed. Used only in CI.

How Signing Works in CI

The release.yml workflow injects both secrets as environment variables:

TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}

tauri-action detects these variables and signs the update artifacts (.tar.gz.sig on macOS, .nsis.zip.sig on Windows). The generated latest.json includes the signatures so the updater plugin can verify them against the embedded public key.

Key Rotation

Rotate the signing key pair on:

  • Major version releases (e.g., v1.0.0 → v2.0.0)
  • Suspected or confirmed key compromise

Rotation Procedure

  1. Generate a new key pair:

    Terminal window
    tauri signer generate -w ~/.tauri/inklings.key

    This outputs the public key to stdout and writes the private key to ~/.tauri/inklings.key.

  2. Update the public key in the repo: Replace the pubkey value in apps/desktop/src-tauri/tauri.conf.jsonplugins.updater.pubkey with the new public key.

  3. Update secrets:

    • Store the new private key and password in 1Password.
    • Update TAURI_SIGNING_PRIVATE_KEY and TAURI_SIGNING_PRIVATE_KEY_PASSWORD in GitHub repository secrets (Settings → Secrets and variables → Actions).
    • Delete ~/.tauri/inklings.key from the local machine after confirming secrets are stored.
  4. Publish a transition release: Users on the old version will verify updates against the old public key. The first release after rotation must be signed with the old key so existing installs can verify and apply it. That release ships the new public key embedded in the binary, so subsequent updates verify against the new key.

    If the old key is compromised and cannot be used, users must manually download and reinstall the app.

  5. Commit and tag: Commit the tauri.conf.json change, merge to production, and tag a new release.

Generating a Key Pair (First Time)

Terminal window
# Install the Tauri CLI if not already available
cargo install tauri-cli
# Generate the key pair
tauri signer generate -w ~/.tauri/inklings.key

The command will:

  • Prompt for a password (use a strong, unique password)
  • Write the encrypted private key to ~/.tauri/inklings.key
  • Print the public key to stdout

Copy the public key into tauri.conf.json and store the private key + password in 1Password, then configure GitHub Actions secrets.

Troubleshooting

SymptomCauseFix
Update downloads but fails to applyPublic key in binary doesn’t match signing keyVerify tauri.conf.json pubkey matches the key pair used in CI
latest.json has no .sig fieldsTAURI_SIGNING_PRIVATE_KEY not set in CIAdd the secret to GitHub Actions
CI build warns “no signing key”Secret name typo or empty valueCheck exact secret names in repository settings
Users can’t update after key rotationTransition release wasn’t signed with old keyUsers must manually reinstall

Was this page helpful?