Claude
Skills
Sign in
Back

signing-tauri-apps

Included with Lifetime
$97 forever

Guides the user through Tauri application code signing and notarization for Android, iOS, Linux, macOS, and Windows platforms including certificate setup and configuration.

General

What this skill does


# Tauri Code Signing Skill

This skill provides comprehensive guidance for code signing Tauri applications across all supported platforms.

## Platform Overview

| Platform | Requirement | Certificate Type |
|----------|-------------|------------------|
| Android | Required for Play Store | Java Keystore (JKS) |
| iOS | Required for distribution | Apple Developer Certificate |
| Linux | Optional (enhances trust) | GPG Key |
| macOS | Required for distribution | Developer ID / Apple Distribution |
| Windows | Required (SmartScreen) | OV or EV Certificate |

---

## Android Signing

### Generate Keystore

**macOS/Linux:**
```bash
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
```

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

### Configuration File

Create `src-tauri/gen/android/keystore.properties`:

```properties
password=<your-password>
keyAlias=upload
storeFile=/path/to/upload-keystore.jks
```

**IMPORTANT:** Never commit `keystore.properties` to version control.

### Gradle Configuration

Modify `src-tauri/gen/android/app/build.gradle.kts`:

```kotlin
import java.io.FileInputStream

// Add before android { } block
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = java.util.Properties()
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

android {
    // ... existing config ...

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

    buildTypes {
        release {
            signingConfig = signingConfigs.getByName("release")
            // ... other release config ...
        }
    }
}
```

### CI/CD Environment Variables

| Variable | Description |
|----------|-------------|
| `ANDROID_KEY_ALIAS` | Key alias (e.g., `upload`) |
| `ANDROID_KEY_PASSWORD` | Keystore password |
| `ANDROID_KEY_BASE64` | Base64-encoded keystore file |

**GitHub Actions Example:**

```yaml
- 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
```

---

## iOS Signing

### Prerequisites

- Apple Developer Program enrollment ($99/year)
- Bundle identifier registered in App Store Connect
- iOS code signing certificate
- Mobile provisioning profile

### Automatic Signing (Recommended)

For local development, authenticate through Xcode Settings > Accounts.

For CI/CD, create an App Store Connect API key and set:

| Variable | Description |
|----------|-------------|
| `APPLE_API_ISSUER` | Issuer ID from App Store Connect |
| `APPLE_API_KEY` | Key ID from App Store Connect |
| `APPLE_API_KEY_PATH` | Path to the `.p8` private key file |

### Manual Signing

| Variable | Description |
|----------|-------------|
| `IOS_CERTIFICATE` | Base64-encoded `.p12` certificate |
| `IOS_CERTIFICATE_PASSWORD` | Password used when exporting certificate |
| `IOS_MOBILE_PROVISION` | Base64-encoded provisioning profile |

### Certificate Types by Distribution Method

| Distribution | Certificate Type |
|--------------|------------------|
| Debugging | Apple Development or iOS App Development |
| App Store | Apple Distribution or iOS Distribution |
| Ad Hoc | Apple Distribution or iOS Distribution |

### Export Certificate

1. Open Keychain Access
2. Find your certificate
3. Right-click the private key
4. Select "Export" and save as `.p12`
5. Convert to base64: `base64 -i certificate.p12`

### Create Provisioning Profile

1. Register App ID with matching bundle identifier
2. Create provisioning profile for your distribution method
3. Link certificate to profile
4. Download and convert: `base64 -i profile.mobileprovision`

---

## Linux Signing (AppImage)

### Generate GPG Key

```bash
gpg2 --full-gen-key
```

Back up the key securely.

### Environment Variables

| Variable | Description |
|----------|-------------|
| `SIGN` | Set to `1` to enable signing |
| `SIGN_KEY` | GPG Key ID (optional, uses default if not set) |
| `APPIMAGETOOL_SIGN_PASSPHRASE` | Key password (required for CI/CD) |
| `APPIMAGETOOL_FORCE_SIGN` | Set to `1` to fail build on signing error |

### Build with Signing

```bash
SIGN=1 APPIMAGETOOL_SIGN_PASSPHRASE="your-passphrase" npm run tauri build
```

### View Embedded Signature

```bash
./src-tauri/target/release/bundle/appimage/app_version_amd64.AppImage --appimage-signature
```

### Validate Signature

Download the validate tool from [AppImageUpdate releases](https://github.com/AppImageCommunity/AppImageUpdate/releases):

```bash
chmod +x validate-x86_64.AppImage
./validate-x86_64.AppImage your-app.AppImage
```

**Note:** AppImage does not auto-validate signatures. Users must manually verify.

---

## macOS Signing and Notarization

### Prerequisites

- Apple Developer Program enrollment ($99/year)
- Mac computer for code signing
- Free accounts cannot notarize applications

### Certificate Types

| Certificate | Use Case |
|-------------|----------|
| Apple Distribution | App Store submissions |
| Developer ID Application | Distribution outside App Store |

### Create Certificate

1. Generate Certificate Signing Request (CSR) from Keychain Access
2. Upload CSR at Apple Developer > Certificates, IDs & Profiles
3. Download and double-click `.cer` to install

### Configuration

**tauri.conf.json:**

```json
{
  "bundle": {
    "macOS": {
      "signingIdentity": "Developer ID Application: Your Name (TEAM_ID)"
    }
  }
}
```

### Environment Variables for CI/CD

**Certificate Variables:**

| Variable | Description |
|----------|-------------|
| `APPLE_CERTIFICATE` | Base64-encoded `.p12` certificate |
| `APPLE_CERTIFICATE_PASSWORD` | Password for exported certificate |
| `APPLE_SIGNING_IDENTITY` | Certificate name in keychain |

**Notarization - Option 1: App Store Connect API (Recommended):**

| Variable | Description |
|----------|-------------|
| `APPLE_API_ISSUER` | Issuer ID |
| `APPLE_API_KEY` | Key ID |
| `APPLE_API_KEY_PATH` | Path to `.p8` private key |

**Notarization - Option 2: Apple ID:**

| Variable | Description |
|----------|-------------|
| `APPLE_ID` | Apple ID email |
| `APPLE_PASSWORD` | App-specific password |
| `APPLE_TEAM_ID` | Team identifier |

### Export Certificate for CI/CD

```bash
# Export from Keychain as .p12, then:
base64 -i certificate.p12 | pbcopy
```

### Ad-Hoc Signing (Testing Only)

For unsigned distribution or testing without Apple credentials:

```json
{
  "bundle": {
    "macOS": {
      "signingIdentity": "-"
    }
  }
}
```

### GitHub Actions Example

```yaml
- name: Import certificate
  env:
    APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
    APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
  run: |
    echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
    security create-keychain -p actions temp.keychain
    security import certificate.p12 -k temp.keychain -P $APPLE_CERTIFICATE_PASSWORD -T /usr/bin/codesign
    security list-keychains -s temp.keychain
    security unlock-keychain -p actions temp.keychain
    security set-key-partition-list -S apple-tool:,apple: -s -k actions temp.keychain
```

---

## Windows Signing

### Certificate Types

| Type | SmartScreen | Availability |
|------|-------------|--------------|
| OV (Organization Validated) | Builds reputation over time | Before June 1, 2023 |
| EV (Extended 

Related in General