Version: v5

CodeSigningPlugin

This plugin can be used to sign chunks so that their integrity can be verified before execution. You should consider code-signing your chunks when you are using code splitting or ModuleFederation and want to deliver parts of your code remotely to the end-user.

Usage

rspack.config.cjs
const Repack = require("@callstack/repack");

module.exports = {
  plugins: [
    new Repack.plugins.CodeSigningPlugin({
      // options
    }),
  ],
};

Options

privateKeyPath

  • Required
  • Type: string

Path to the private key. This can be either a relative path or an absolute one. Relative paths are resolved within context provided with project configuration.

enabled

  • Type: boolean
  • Default: true

Whether to enable the plugin. You typically want to enable the plugin only for production builds and disable it for development.

exludeChunks

  • Type: string[] | RegExp | RegExp[]
  • Default: []

Names of chunks to exclude from code-signing. You might want to use this if some of the chunks in your setup are not being delivered remotely and don't need to be verified.

Guide

To add code-signing to your app, you first need to generate a pair of cryptographic keys that will be used for both signing the bundles (private key) and verifying their integrity in runtime.

Creating key pair

In terminal, navigate to your project directory and enter the following commands:

ssh-keygen -t rsa -b 4096 -m PEM -f code-signing.pem
openssl rsa -in code-signing.pem -pubout -outform PEM -out code-signing.pem.pub

Add the plugin

After that, you need to add CodeSigningPlugin to your configuration. Make sure the privateKeyPath points to the location of your code-signing.pem.

rspack.config.cjs
1const Repack = require("@callstack/repack");
2
3module.exports = (env) => {
4  const { mode } = env;
5  return {
6    plugins: [
7      new Repack.RepackPlugin(),
8      new Repack.plugins.CodeSigningPlugin({
9        enabled: mode === "production",
10        privateKeyPath: "./code-signing.pem",
11      }),
12    ],
13  };
14};

Add the public key

To be able to verify the bundles in runtime, we need to add the public key (code-signing.pem.pub) to the app assets. The public key needs to be included for every platform separately.

iOS

You need to add the public key to ios/<appName>/Info.plist under the name RepackPublicKey. Add the following to your Info.plist and then copy the contents of code-signing.pem.pub and paste them inside of the <string> tags:

Info.plist
<plist>
<dict>
	<key>RepackPublicKey</key>
	<string>
        <!-- contents of your code-signing.pem.pub -->
	</string>
</dict>
</plist>

Android

You need to add the public key to android/app/src/main/res/values/strings.xml under the name RepackPublicKey. Add the following to your strings.xml and then copy the contents of code-signing.pem.pub and paste them inside of the <string> tags:

strings.xml
<resources>
	<string name="RepackPublicKey">
        <!-- contents of your code-signing.pem.pub -->
	</string>
</resources>

Enable verification

By default, the bundles are not verified since code-signing is entirely optional. You can enable bundle verification by modyifing the return value of resolver added through ScriptManager.shared.addResolver.

Integrity verification can be set (through verifyScriptSignature) to one of the 3 levels:

ValueDescription
strictAlways verify the integrity of the bundle
laxVerify the integrity only if the signtarure is present
offNever verify the integrity of the bundle

Go to index.js and modify your ScriptManager setup like this:

index.js
1import { ScriptManager, Federated } from "@callstack/repack/client";
2
3const containers = {
4  MiniApp: "http://localhost:9000/[name][ext]",
5};
6
7ScriptManager.shared.addResolver(async (scriptId, caller) => {
8  const resolveURL = Federated.createURLResolver({ containers });
9
10  const url = resolveURL(scriptId, caller);
11  if (url) {
12    return {
13      url,
14      query: { platform: Platform.OS },
15      verifyScriptSignature: __DEV__ ? "off" : "strict",
16    };
17  }
18});