If you compare live update solutions for long enough, you will run into a security claim that sounds decisive: "end-to-end encrypted." It suggests that solutions offering encryption are more secure than solutions that "only" sign their updates. That framing mixes up what the individual security controls in an update pipeline actually do. In this post, we walk through the threat model of live updates (also known as OTA updates or CodePush): what HTTPS already protects, what code signing guarantees, what encryption adds on top, and which of these properties matter for your app. By the end, you can evaluate the security of any live update solution based on facts instead of buzzwords.
Key Takeaways
- HTTPS protects update bundles in transit. It does not protect against a compromised update service, storage bucket, or CDN.
- Code signing with a developer-held private key guarantees authenticity and integrity all the way to the device: even a fully compromised update infrastructure cannot inject code into your app.
- Encrypting bundles adds confidentiality only. It provides no additional protection against malicious updates.
- Client-side encryption cannot keep app code secret, because the decryption key must ship inside the app binary. The React Native maintainers state it plainly: "Code on the client is not secret."
- If bundles must stay confidential, for example in privately distributed enterprise apps, self-hosting them is a stronger control than encrypting them.
The Trust Chain of a Live Update
Every live update passes through the same chain: you build a web bundle in your CI/CD pipeline, upload it to an update service, the service stores and serves it (usually through a CDN), and the Live Update SDK in your app downloads and installs it. Security along this chain means three different properties:
- Authenticity: The update genuinely comes from you.
- Integrity: The update was not modified on the way.
- Confidentiality: No third party can read the update's content.
For code that ends up running on your users' devices, authenticity and integrity are non-negotiable. A single malicious bundle can compromise every device that installs it. Confidentiality plays a much smaller role than most marketing suggests, and we will look at why below.
What HTTPS Already Protects
HTTPS encrypts and authenticates the connection between the device and the server it downloads from. It reliably prevents on-path attackers, for example on public Wi-Fi or at the ISP level, from reading or modifying an update in transit.
What HTTPS cannot do is vouch for the endpoints themselves. It says nothing about what happened to a bundle before it entered the pipe: if the update service, its storage, or its CDN is compromised, HTTPS will faithfully deliver the attacker's bundle with a valid certificate. Every serious live update solution uses HTTPS, so transport security is not where solutions differ.
What Code Signing Protects
Code signing guarantees both authenticity and integrity, independent of the infrastructure in between. You sign each bundle with a private key when uploading, typically in your CI/CD pipeline, and the app verifies the signature with an embedded public key before applying the update. If verification fails, the update is discarded and the app keeps running its current bundle.
This is the control that addresses the threat that actually matters: a compromised update pipeline. Because the private key stays with you, for example in your CI/CD secret store, an attacker who took over the update service, the storage, or the CDN still could not produce a bundle your app would accept. With code signing enabled, you don't have to trust your update provider to be uncompromised.
Capawesome Cloud implements this with a standard RSA key pair. You generate the pair with the Capawesome CLI, keep the private key, and embed the public key in your app. Signing then happens as part of the upload:
npx @capawesome/cli apps:liveupdates:upload --private-key private.pem
Verification on the device fails closed, and protected channels require signed bundles. You can find the full setup in the Code Signing documentation.
Do Live Updates Need End-to-End Encryption?
For most apps, no. End-to-end encryption of update bundles adds exactly one property: confidentiality toward the update service and its storage. It adds nothing to authenticity or integrity that code signing does not already provide, so it does not make updates any harder to forge or tamper with.
The deeper problem is that confidentiality of app code is not achievable for a publicly distributed app. Your web bundle is delivered to every user's device, where it is stored and executed, and anyone can download your app from the App Store or Play Store and read it with freely available tools. For the app to decrypt updates, the decryption key must ship inside the app binary, so anyone can extract that key too, including any party the encryption was meant to keep out. The React Native core team declined to add bundle encryption to the framework for exactly this reason: "Code on the client is not secret - secrets should be kept on the server."
A live update solution that combines HTTPS with developer-held code signing already guarantees that nobody, including the update service itself, can modify your updates or inject code into your app. Encryption on top of that does not make a solution more secure for a public app; it addresses a property that public distribution gives up by design.
There are legitimate niches. If your app is distributed privately, for example through mobile device management (MDM) in an enterprise, outsiders cannot obtain your binary, and encrypting bundles genuinely keeps their content away from the update provider. Encryption can also limit the impact of a storage breach while a bundle is staged but not yet rolled out. If those scenarios are part of your threat model, though, there is a control that solves them more thoroughly.
When Confidentiality Matters: Self-Host Your Bundles
Instead of encrypting bundles so that a third party cannot read them, you can remove the third party from the data path entirely. Capawesome Cloud supports self-hosting bundles: your bundles stay on your own servers, and only the metadata required to check for updates is exchanged with the Cloud. Devices download bundles directly from your infrastructure over HTTPS.
Code signing works the same way as with hosted bundles, so you keep the authenticity and integrity guarantees on top of full confidentiality. No encryption scheme with an extractable key can match a setup where the provider never holds the artifact at all. Self-hosting is also the answer to data residency and compliance policies that prohibit sharing build artifacts with third parties.
Live Update Security Best Practices
Beyond choosing a solution with the right controls, most of your security posture comes down to how you configure it:
- Enable code signing in production. It is the single control that protects you even if the update infrastructure is compromised. Follow the Code Signing guide to set it up.
- Guard your private key. Store it in your CI/CD secret store and never commit it to version control.
- Use protected channels. Protected channels require signed bundles, so an unsigned bundle can never slip through.
- Keep secrets out of bundles. Treat every bundle as public. API keys and credentials belong on your server, whether or not your update pipeline encrypts anything.
- Roll out gradually and be ready to roll back. Gradual rollouts limit how many devices a bad update can reach, and rollbacks let you recover in minutes.
- Self-host bundles if your policies require it. Self-hosting keeps your artifacts on your own infrastructure without giving up signing.
Capawesome Cloud ships with all of these controls built in, so you can start with a secure setup from day one.
FAQ
Is end-to-end encryption more secure than code signing for OTA updates?
They protect different properties, and for publicly distributed apps, code signing covers the one that matters. Signing guarantees that only bundles produced with your private key are ever installed, which protects against compromised update infrastructure. Encryption only hides bundle content from the update provider, and that guarantee is weakened by the fact that the decryption key ships inside every app binary. An update pipeline with HTTPS and developer-held code signing is not less secure because it skips bundle encryption.
Can someone read my live update bundles?
Yes, and you should plan for it. Live update bundles are web assets (HTML, CSS, and JavaScript) that are delivered to and stored on every user's device, so anyone can extract them from your app, with or without encryption in the delivery pipeline. Keep secrets such as API keys on your server and treat everything inside a bundle as public.
What happens if the update service itself is compromised?
With code signing enabled, nothing gets installed. The app verifies every downloaded bundle against your public key before applying it. A bundle that was not signed with your private key fails verification, is discarded, and the app keeps running its current version. This is why the private key must remain under your control.
Does code signing work with self-hosted bundles?
Yes. With Capawesome Cloud, you sign self-hosted bundles when registering them with the CLI, and devices verify the signature after downloading from your server, exactly as with hosted bundles. Combined, self-hosting and code signing give you confidentiality, authenticity, and integrity at the same time.
Are live updates as secure as app store updates?
With code signing enabled, they follow the same trust model. App store updates are signed by the developer and verified by the operating system before installation. Signed live updates are signed with your private key and verified by the Live Update SDK before being applied. In both cases, only code that you produced, unmodified, reaches your users.
Conclusion
When you evaluate the security of a live update solution, match each feature to the property it protects. HTTPS covers the network. Code signing with a key that only you hold covers malicious updates, including the case where the update service itself is compromised. Confidentiality is the outlier: for publicly distributed apps, no client-side encryption scheme can fully deliver it, and where it genuinely matters, self-hosting provides it architecturally. Capawesome Cloud combines all three controls: HTTPS delivery, developer-held code signing with fail-closed verification, and optional self-hosting.
For a look at how signing and verification are implemented on Android and iOS, read How Capacitor Live Updates Work Under the Hood. And since security is only one half of evaluating a provider, our Capacitor live update reliability guide covers the other: uptime claims, SLAs, and rollback plans. Join the Capawesome Discord server if you have questions, and subscribe to the Capawesome newsletter to stay updated on the latest news.
Top comments (0)