---
title: Sign Your Live Update Bundles
description: Sign Live Update bundles with an RSA key pair so your Capacitor or Cordova app only applies updates that come from you and haven't been tampered with.
---

# Sign Your Bundles

Code signing lets your app verify the **authenticity** and **integrity** of every Live Update before applying it — so only bundles you produced, unmodified, are ever installed. Even though delivery is over HTTPS, signing is defense in depth, and is required for [protected channels](channels.md#protected-channels).

The mechanism is a standard RSA key pair: you sign each bundle with your **private** key when uploading, and your app verifies the signature with the embedded **public** key.

## Generate the key pair

Generate a key pair with the [Capawesome CLI](../cli/index.md):

```bash
npx @capawesome/cli apps:liveupdates:generatesigningkey
```

This creates `private.pem` (keep it secret) and `public.pem`. You can customize the paths and key size:

```bash
npx @capawesome/cli apps:liveupdates:generatesigningkey --private-key-path=./keys/private.pem --public-key-path=./keys/public.pem --key-size=4096
```

!!! warning "Keep your private key safe"

    Never commit your private key to version control — add `private.pem` to your `.gitignore`.

## Create a signed bundle

Pass the private key with `--private-key` when uploading:

```bash
npx @capawesome/cli apps:liveupdates:upload --private-key private.pem
```

## Configure the public key

Add the public key to your app's configuration so it can verify signatures. The `generatesigningkey` command prints the value preformatted (no line breaks) so you can paste it directly.

=== "Capacitor"

    ```json title="capacitor.config.json"
    {
      "plugins": {
        "LiveUpdate": {
          "publicKey": "-----BEGIN PUBLIC KEY-----MIGf...IDAQAB-----END PUBLIC KEY-----"
        }
      }
    }
    ```

=== "Cordova"

    ```xml title="config.xml"
    <preference name="PUBLIC_KEY" value="-----BEGIN PUBLIC KEY-----MIGf...IDAQAB-----END PUBLIC KEY-----" />
    ```

From now on, your app verifies every downloaded bundle and refuses to apply anything not signed by your private key. We strongly recommend enabling code signing in production, especially if you operate multiple channels or [self-host](self-hosting.md) your bundles.

!!! note "No line breaks"

    The public key value must **not** contain line breaks. The CLI formats it correctly, so copy it directly from the output.

## Bonus: Video Walkthrough

<div style="margin-top: 1rem;">
  <iframe
    width="100%"
    height="450px"
    src="https://www.youtube-nocookie.com/embed/Z-Qu2f-ODv8?rel=0&modestbranding=1"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen
  ></iframe>
</div>

## Next steps

- [Protect your channels](channels.md#protected-channels) — require signed bundles before anything can be distributed.
- [Self-host your bundles](self-hosting.md) — keep your web artifacts on your own infrastructure, combined with code signing.
