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
| Asset | Location | Notes |
|---|---|---|
| Public key | apps/desktop/src-tauri/tauri.conf.json → plugins.updater.pubkey | Committed to repo. Base64-encoded minisign public key. |
| Private key | 1Password + GitHub Actions secret TAURI_SIGNING_PRIVATE_KEY | Never committed. Used only in CI. |
| Private key password | 1Password + GitHub Actions secret TAURI_SIGNING_PRIVATE_KEY_PASSWORD | Never 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
-
Generate a new key pair:
Terminal window tauri signer generate -w ~/.tauri/inklings.keyThis outputs the public key to stdout and writes the private key to
~/.tauri/inklings.key. -
Update the public key in the repo: Replace the
pubkeyvalue inapps/desktop/src-tauri/tauri.conf.json→plugins.updater.pubkeywith the new public key. -
Update secrets:
- Store the new private key and password in 1Password.
- Update
TAURI_SIGNING_PRIVATE_KEYandTAURI_SIGNING_PRIVATE_KEY_PASSWORDin GitHub repository secrets (Settings → Secrets and variables → Actions). - Delete
~/.tauri/inklings.keyfrom the local machine after confirming secrets are stored.
-
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.
-
Commit and tag: Commit the
tauri.conf.jsonchange, merge toproduction, and tag a new release.
Generating a Key Pair (First Time)
# Install the Tauri CLI if not already availablecargo install tauri-cli
# Generate the key pairtauri signer generate -w ~/.tauri/inklings.keyThe 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
| Symptom | Cause | Fix |
|---|---|---|
| Update downloads but fails to apply | Public key in binary doesn’t match signing key | Verify tauri.conf.json pubkey matches the key pair used in CI |
latest.json has no .sig fields | TAURI_SIGNING_PRIVATE_KEY not set in CI | Add the secret to GitHub Actions |
| CI build warns “no signing key” | Secret name typo or empty value | Check exact secret names in repository settings |
| Users can’t update after key rotation | Transition release wasn’t signed with old key | Users must manually reinstall |
Was this page helpful?
Thanks for your feedback!