---
title: Live Update Security Best Practices
description: Secure your Capacitor and Cordova Live Updates — code signing, key custody, protected channels, automatic rollbacks, and what never belongs in a bundle.
---

# Security

A Live Update replaces the web code running inside your app, so the update path deserves the same care as your release pipeline. This page collects the practices we recommend for production apps. For account-level practices — API tokens, roles, two-factor authentication, and audit logs — see [Cloud security](../security.md).

## Sign your bundles

[Code signing](code-signing.md) is the most effective control. Your app verifies an RSA signature before it applies a bundle, so anything that wasn't produced by you — or that was modified after upload — is rejected, even if an attacker managed to serve it.

Where you sign decides who holds the private key:

- **Sign locally or in your own CI.** You pass `--private-key` when uploading a bundle, so the key never leaves your machine or your CI secret store, and Capawesome Cloud only ever receives an already signed bundle. This is the strongest setup: nobody at Capawesome can sign a bundle in your name.
- **Sign in Capawesome Cloud.** If Capawesome Cloud builds your web bundle for you, it also signs the bundle, which means you upload your private key as a [web signing certificate](../native-builds/certificates/web.md). Your key then lives outside your own infrastructure and is used on your behalf. That's the trade-off for letting us build your web bundle, and it's one to make deliberately: if your threat model requires that only you can ever sign a bundle, build and sign the web bundle in your own pipeline and use Capawesome Cloud for your Android and iOS builds.

Either way, never commit the private key to version control, and keep a backup — losing it means shipping a new native version with a new public key.

## Protect your production channels

A [protected channel](channels.md#protected-channels) only distributes signed bundles. Mark your production channel as protected so an unsigned bundle can't reach users because someone forgot a flag in a pipeline.

## Enable automatic rollbacks

A bad bundle can take your app down for everyone on the channel until you ship a fix. The SDK can recover on its own. Set `readyTimeout` and `autoBlockRolledBackBundles`, and call `ready()` as early in your bootstrap as possible. If `ready()` doesn't run in time, the SDK falls back on the next launch to the bundle shipped with the installed binary, which is known to run on that binary. See [Automatic rollbacks](rollbacks.md#automatic-rollbacks) for the configuration.

Without it, your only path back is a [manual rollback](rollbacks.md#manual-rollbacks), and users whose app no longer starts may never check for another update.

## Never ship sensitive data in a bundle

A bundle is client code. It is delivered to every device on the channel, and anyone with the app can extract and read it — obfuscation doesn't change that. Keep out of it:

- **API keys and secrets** for services that charge money or grant write access. Call those services from your backend instead.
- **Credentials of any kind**, including database connection strings, private certificates, and signing keys.
- **Personal data** in fixtures, seed files, or test data. Use anonymized values.
- **Internal endpoints and debug tooling** you don't want exposed, such as admin URLs or verbose logging left enabled.

Treat a bundle exactly like a public web build, because that's what it is. If something must stay private, it belongs on your server behind an authenticated endpoint.

## Next steps

- [Cloud security](../security.md) — protect your API tokens and limit who can publish.
- [Sign your bundles](code-signing.md) — set up an RSA key pair and verify signatures in your app.
- [Self-host bundles](self-hosting.md) — keep your web artifacts on your own infrastructure.
- [Privacy & data residency](privacy.md) — what data Live Updates collect and how to stay on EU servers.
