Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions src/content/docs/distribute/Signing/android.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
title: Android Code Signing
sidebar:
label: Android
order: 5
---

import { Tabs, TabItem } from '@astrojs/starlight/components';
import { Code } from '@astrojs/starlight/components';

To publish on the Play Store, you need to sign your app with a digital certificate.

Android App Bundles and APKs must be signed before being uploaded for distribution.

Google also provides an additional signing mechanism for Android App Bundles distributed in the Play Store.
See the [official Play App Signing documentation] for more information.

## Creating a keystore and upload key

Android signing requires a Java Keystore file that can be generated using the official `keytool` CLI:

<Tabs>
<TabItem label="macOS / Linux">

```
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
```

</TabItem>

<TabItem label="Windows">

```
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload
```

</TabItem>
</Tabs>

This command stores the `upload-keystore.jks` file in your home directory.
If you want to store it elsewhere, change the argument you pass to the `-keystore` parameter.

:::tip

- The `keytool` command might not be in your PATH.
You may find it installed in the JDK that is installed with Android Studio:

<Tabs>

<TabItem label="Linux">
<Code code="/opt/android-studio/jbr/bin/keytool ...args" lang="sh" />
**Android Studio directory path depends on your Linux distribution**
</TabItem>

<TabItem label="macOS">
<Code
code="/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/keytool ...args"
lang="sh"
/>
</TabItem>

<TabItem label="Windows">
<Code
code="C:\\Program Files\\Android\\Android Studio\\jbr\\bin\\keytool.exe ...args"
lang="sh"
/>
</TabItem>

</Tabs>

:::

:::caution[Security Warning]

Keep the `keystore` file private; don't check it into public source control!

:::

See the [official documentation](https://developer.android.com/studio/publish/app-signing#generate-key) for more information.

## Configure the signing key

Create a file named `[project]/src-tauri/gen/android/keystore.properties` that contains a reference to your keystore:

```
password=<password defined when keytool was executed>
keyAlias=upload
storeFile=<location of the key store file, such as /Users/<user name>/upload-keystore.jks or C:\\Users\\<user name>\\upload-keystore.jks>
```

:::caution[Security Warning]
Keep the `keystore.properties` file private; don't check it into public source control.
:::

You will usually generate this file in your CI/CD platform. The following snippet contains an example job step for GitHub Actions:

```yml
- name: setup Android signing
run: |
cd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks
echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties
```

In this example the keystore was exported to base64 with `base64 -i /path/to/keystore.jks` and set as the `ANDROID_KEY_BASE64` secret.

### Configure Gradle to use the signing key

Configure gradle to use your upload key when building your app in release mode by editing the `[project]/src-tauri/gen/android/app/build.gradle.kts` file.

1. Add the needed import at the beginning of the file:

```kotlin
import java.io.FileInputStream
```

2. Add the `release` signing config before the `buildTypes` block:

```kotlin {3-12}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}

buildTypes {
...
}
```

3. Use the new `release` signing config in the `release` config in `buildTypes` block:

```kotlin {3}
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
```

Release builds of your app will now be signed automatically.

[official Play App Signing documentation]: https://support.google.com/googleplay/android-developer/answer/9842756?hl=en&visit_id=638549803861403647-3347771264&rd=1
98 changes: 98 additions & 0 deletions src/content/docs/distribute/Signing/ios.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: iOS Code Signing
sidebar:
label: iOS
order: 4
---

Code signing on iOS is required to distribute your application through the official [Apple App Store] or possibly alternative marketplaces in the European Union and in general to install and execute on end user devices.

## Prerequisites

Code signing on iOS requires enrolling to the [Apple Developer] program, which at the time of writing costs 99$ per year.
You also need an Apple device where you perform the code signing. This is required by the signing process and due to Apple's Terms and Conditions.

To distribute iOS applications you must have your bundle identifier registered in the App Store Connect,
an appropriate iOS code signing certificate and a mobile provisioning profile that links them together and enables the iOS capabilities used by your app.
These requirements can be either automatically managed by Xcode or provided manually.

## Automatic Signing

Letting Xcode manage the signing and provisioning for your app is the most convenient way to export your iOS app to be distributed.
It automatically registers your bundle identifier, manages iOS capabilities changes, and configures an appropriate certificate based on your export method.

Automatic signing is enabled by default, and uses the account configured in Xcode to authenticate when used on your local machine.\
To register your account, open the Xcode application and open the Settings page in the `Xcode > Settings` menu, switch to the Accounts tab and click the `+` icon.

To use the automatic signing in CI/CD platforms you must create an App Store Connect API key
and define the `APPLE_API_ISSUER`, `APPLE_API_KEY` and `APPLE_API_KEY_PATH` environment variables.\
Open the [App Store Connect's Users and Access page], select the Keys tab, click on the Add button and select a name and the Developer access.
The `APPLE_API_ISSUER` (Issuer ID) is presented above the keys table, and the `APPLE_API_KEY` is the value on the Key ID column on that table.
You also need to download the private key, which can only be done once and is only visible after a page reload (the button is shown on the table row for the newly created key).
The private key file path must be set via the `APPLE_API_KEY_PATH` environment variable.

## Manual Signing

To manually sign your iOS app you can provide the certificate and mobile provisioning profile via environment variables:

- **IOS_CERTIFICATE**: base64 representation of the certificate exported from the Keychain.
- **IOS_CERTIFICATE_PASSWORD**: password of the certificate set when exporting it from the Keychain.
- **IOS_MOBILE_PROVISION**: base64 representation of the provisioning profile.

The following sections explain how to get these values.

### Signing Certificate

After enrolling, navigate to the [Certificates] page to create a new Apple Distribution certificate.
Download the new certificate and install it to the macOS Keychain.

To export the certificate key, open the "Keychain Access" app, expand the certificate's entry,
right-click on the key item and select "Export \<key-name\>" item.
Select the path of the exported .p12 file and remember its password.

Run the following `base64` command to convert the certificate to base64 and copy it to the clipboard:

```
base64 -i <path-to-certificate.p12> | pbcopy
```

The value in the clipboard is now the base64 representation of the signing certificate.
Save it and use it as the `IOS_CERTIFICATE` environment variable value.

The certificate password must be set to the `IOS_CERTIFICATE_PASSWORD` variable.

:::tip[Choose Certificate Type]
You must use an appropriate certificate type for each export method:

- **debugging**: Apple Development or iOS App Development
- **app-store-connect**: Apple Distribution or iOS Distribution (App Store Connect and Ad Hoc)
- **ad-hoc**: Apple Distribution or iOS Distribution (App Store Connect and Ad Hoc)

:::

### Provisioning Profile

Additionally, you must provide the provisioning profile for your application.
In the [Identifiers](https://developer.apple.com/account/resources/identifiers/list) page,
create a new App ID and make sure its "Bundle ID" value matches the identifier set in the [`identifier`] configuration.

Navigate to the [Profiles](https://developer.apple.com/account/resources/profiles/list) page to create a new provisioning profile.
For App Store distribution, it must be an "App Store Connect" profile.
Select the appropriate App ID and link the certificate you previously created.

After creating the provisioning profile, download it and run the following `base64` command to convert the profile and copy it to the clipboard:

```
base64 -i <path-to-profile.mobileprovision> | pbcopy
```

The value in the clipboard is now the base64 representation of the provisioning profile.
Save it and use it as the `IOS_MOBILE_PROVISION` environment variable value.

Now you can build your iOS application and distribute on the App Store!

[Certificates]: https://developer.apple.com/account/resources/certificates/list
[Apple Developer]: https://developer.apple.com
Comment thread
tweidinger marked this conversation as resolved.
[Apple App Store]: https://www.apple.com/app-store/
[App Store Connect's Users and Access page]: https://appstoreconnect.apple.com/access/users
[`identifier`]: /reference/config/#identifier
56 changes: 56 additions & 0 deletions src/content/docs/distribute/Signing/linux.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Linux Code Signing
sidebar:
label: Linux
order: 3
---

This guide provides information on code signing for Linux packages.
Comment thread
tweidinger marked this conversation as resolved.
While artifact signing is not required for your application to be deployed on Linux,
it can be used to increase trust into your deployed application.
Signing the binaries allows your end user to verify that these are genuine and have not been modified by another untrusted entity.

## Signing for AppImages

The AppImage can be signed using either gpg or gpg2.

### Prerequisites

A key for signing must be prepared. A new one can be generated using:

```shell
gpg2 --full-gen-key
```

Please refer to the gpg or gpg2 documentation for additional information.
You should take additional care to back up your private and public keys in a secure location.

### Signing

You can embed a signature in the AppImage by setting the following environment variables:

- **SIGN**: set to `1` to sign the AppImage.
- **SIGN_KEY**: optional variable to use a specific GPG Key ID for signing.
- **APPIMAGETOOL_SIGN_PASSPHRASE**: the signing key password. If unset, gpg shows a dialog so you can input it. You must set this when building in CI/CD platforms.
- **APPIMAGETOOL_FORCE_SIGN**: by default the AppImage is generated even if signing fails. To exit on errors, you can set this variable to `1`.

You can display the signature embedded in the AppImage by running the following command:

```shell
./src-tauri/target/release/bundle/appimage/$APPNAME_$VERSION_amd64.AppImage --appimage-signature
```

Note that you need to change the $APPNAME and $VERSION values with the correct ones based on your configuration.

:::caution The signature is not verified

AppImage does not validate the signature, so you can't rely on it to check whether the file has been tampered with or not.
To validate the signature, you must provide an external tool for your users.
This requires you to publish your public key on an authenticated channel (e.g. your website served via TLS),
so the end user can download and verify.

See [the official AppImage documentation] for additional information.

:::

[the official appimage documentation]: https://docs.appimage.org/packaging-guide/optional/signatures.html
Loading