Skip to content
Back to skills

Rust App Distribution

BSecurity

Distribution pipeline for signed Rust desktop applications -- code signing, notarization, auto-updates, and package manager distribution. Activate on: code signing, macOS notarization, Apple Developer, Authenticode, Windows signing, auto-updater, Homebrew formula, winget manifest, Scoop bucket, Tauri updater, app distribution, release pipeline. NOT for: library crate publishing (use crates.io docs), web deployment (use devops-automator).

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
devopstypescriptrustgobashazuretestinggitfrontendbackenddevops

Works with

  • cli

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro scans all 4 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add curiositech/port-daddy --skill rust-app-distribution --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rust App Distribution?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rust App Distribution
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/curiositech-rust-app-distribution-port-daddy/badge)](https://www.skillsdirectory.com/skills/curiositech-rust-app-distribution-port-daddy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
license: Apache-2.0
name: rust-app-distribution
description: >-
  Distribution pipeline for signed Rust desktop applications -- code signing, notarization, auto-updates, and package
  manager distribution. Activate on: code signing, macOS notarization, Apple Developer, Authenticode, Windows signing,
  auto-updater, Homebrew formula, winget manifest, Scoop bucket, Tauri updater, app distribution, release pipeline. NOT
  for: library crate publishing (use crates.io docs), web deployment (use devops-automator).
allowed-tools: Read,Write,Edit,Bash(cargo:*,npm:*,npx:*,gh:*,security:*,codesign:*,xcrun:*),Glob,Grep
metadata:
  category: Desktop & Native
  tags:
    - code-signing
    - notarization
    - distribution
    - auto-updater
    - homebrew
    - winget
    - release-pipeline
    - rust
    - packaging
    - binary
    - deployment
  pairs-with:
    - skill: rust-tauri-development
      reason: Tauri apps need signing and distribution
    - skill: cross-platform-desktop
      reason: Platform-specific installer and signing requirements
    - skill: devops-automator
      reason: CI/CD infrastructure for automated builds and releases
  io-contract:
    kind: deliverable
    produces:
      - kind: distribution-pipeline
        description: >-
          Complete CI/CD workflow configuration for code signing, notarization, and package manager publishing across
          macOS and Windows
        format: yaml
      - kind: certificate-setup-guide
        description: >-
          Step-by-step instructions for obtaining and configuring code signing certificates (Apple Developer ID, Windows
          EV, Azure Trusted Signing)
        format: markdown
      - kind: auto-updater-implementation
        description: >-
          Tauri updater configuration with signing key generation, manifest JSON structure, and endpoint setup for
          GitHub releases or custom servers
        language: json
        format: json
      - kind: package-manager-manifest
        description: >-
          Homebrew formula, winget manifest, or Scoop bucket configuration for distributing the application across
          package managers
        format: yaml
      - kind: troubleshooting-runbook
        description: >-
          Diagnostic procedures and fixes for notarization failures, SmartScreen warnings, signature mismatches,
          certificate expiry, and cross-platform binary issues
        format: markdown
---

# Rust App Distribution

Ship signed Rust desktop applications to users on macOS and Windows. This skill covers the full distribution pipeline: code signing certificates, Apple notarization, Windows Authenticode, auto-updater mechanisms, and publishing to package managers (Homebrew, winget, Scoop).

## Decision Points

### Certificate Selection Decision Tree

**IF** macOS distribution needed:
- → **THEN** Apple Developer Program required ($99/year)
- → Generate Developer ID Application cert (automatic with membership)
- → For installers: also generate Developer ID Installer cert

**IF** Windows distribution AND budget < $50/month:
- → **THEN** use EV certificate from DigiCert/Sectigo ($300-500/year)
- → Store on hardware HSM or Azure Key Vault
- → **ELSE IF** US/Canada business with 3+ years history:
  - → Use Azure Trusted Signing ($9.99/month)
  - → Faster setup, cloud-based HSM

**IF** CI platform is GitHub Actions:
- → **THEN** use tauri-action for automated builds
- → Store certs in GitHub Secrets
- → **ELSE IF** CI platform is Azure DevOps:
  - → Use Azure Trusted Signing integration
  - → Store Apple certs in Azure Key Vault

### Auto-Updater Implementation Decision

**IF** simple GitHub-hosted releases:
- → **THEN** use Tauri updater with GitHub releases endpoint
- → Generate signing keys: `cargo tauri signer generate`
- → Point to: `https://github.com/ORG/REPO/releases/latest/download/latest.json`

**IF** custom release infrastructure needed:
- → **THEN** implement custom update endpoint
- → Return JSON with version/signature/download URLs
- → Use CDN for binary hosting

**IF** enterprise deployment with restricted internet:
- → **THEN** implement internal update server
- → Mirror updates behind corporate firewall
- → Use same Tauri updater JSON format

### Package Manager Distribution Decision

**IF** macOS users AND want simple install:
- → **THEN** create Homebrew tap
- → Generate formula with `komac` or manually
- → Automate SHA256 updates in CI

**IF** Windows users AND mainstream distribution:
- → **THEN** submit to winget
- → Use `komac` for manifest generation
- → Submit PR to microsoft/winget-pkgs

**IF** Windows power users OR faster approval:
- → **THEN** create Scoop bucket
- → JSON manifests simpler than winget
- → Faster than winget review process

## Failure Modes

### Notarization Rejection ("Invalid Entitlements")

**Detection rule**: `xcrun notarytool` returns "The entitlements in the app are invalid" or similar entitlement errors.

**Symptom**: Notarization fails despite valid signing.

**Diagnosis**: 
- App requests entitlements not available to Developer ID
- Hardened runtime flags conflict with entitlements
- Using entitlements meant for Mac App Store

**Fix**:
```bash
# Check current entitlements
codesign -d --entitlements - MyApp.app

# Remove Mac App Store entitlements, keep only:
# - com.apple.security.cs.allow-jit (if needed)
# - com.apple.security.cs.allow-unsigned-executable-memory (if needed)
# - com.apple.security.cs.disable-library-validation (if needed)
# - com.apple.security.network.client (for network access)
```

### SmartScreen Reputation Warning ("Publisher Unknown")

**Detection rule**: Windows users report "Windows protected your PC" even with valid EV certificate.

**Symptom**: Valid signature but SmartScreen still warns about unknown publisher.

**Diagnosis**: 
- New certificate without established reputation
- Low download volume (< 1000 downloads)
- Binary not seen by enough Windows Defender users

**Fix**:
1. **Immediate**: Add certificate to Microsoft's reputation system via Partner Center
2. **Long-term**: Accumulate downloads and user reports
3. **Workaround**: Submit binary to Microsoft for manual review
4. **Alternative**: Use extended validation (EV) certificate for faster trust

### Auto-Updater Signature Mismatch

**Detection rule**: Update check succeeds but installation fails with signature verification error.

**Symptom**: App downloads update but refuses to install.

**Diagnosis**:
- Update manifest signed with different key than expected
- Manifest JSON malformed or missing signature field
- Binary tampered with during upload

**Fix**:
```bash
# Verify signature manually
cargo tauri signer verify \
  --public-key-path ~/.tauri/myapp.pub \
  --signature-path release.sig \
  --file MyApp-setup.exe

# Check manifest format
curl -s https://releases.myapp.com/latest.json | jq .

# Re-sign update if signature invalid
cargo tauri signer sign \
  --private-key-path ~/.tauri/myapp.key \
  --file MyApp-setup.exe
```

### Build Pipeline Certificate Expiry

**Detection rule**: CI builds start failing with "certificate not found" or "certificate expired" errors.

**Symptom**: Previously working builds suddenly fail during signing step.

**Diagnosis**:
- Apple Developer ID certificate expired (1 year validity)
- Windows EV certificate expired
- Apple app-specific password revoked

**Fix**:
1. **Apple**: Renew certificate in Apple Developer portal, export new .p12
2. **Windows**: Renew EV certificate with provider, update KeyVault
3. **Update secrets**: Replace base64-encoded certificates in CI secrets
4. **Test**: Run manual build to verify new certificates work

### Cross-Platform Binary Mismatch

**Detection rule**: Package manager users report "architecture not supported" or binary won't launch.

**Symptom**: Installer downloads but app won't run on user's architecture.

**Diagnosis**:
- Built x86_64 binary but user has ARM64 machine
- Universal binary not actually universal
- Wrong target specified in CI matrix

**Fix**:
```yaml
# Ensure complete architecture matrix
strategy:
  matrix:
    include:
      - os: macos-latest
        target: aarch64-apple-darwin
      - os: macos-13  # Intel runner
        target: x86_64-apple-darwin
      - os: windows-latest
        target: x86_64-pc-windows-msvc

# Verify binary architecture
file target/release/myapp  # Should show correct arch
lipo -info target/release/myapp  # macOS universal binary check
```

## Worked Examples

### Complete Release Pipeline Setup

**Scenario**: Setting up automated releases for a Tauri app "DevTools" that needs macOS and Windows distribution.

**Step 1 - Certificate Setup**:
```bash
# Generate Apple Developer ID (via Apple Developer portal)
# Download .p12 file, encode for CI:
base64 -i ~/Downloads/certificates.p12 -o apple_cert.txt

# For Windows - setup Azure Trusted Signing:
# 1. Create account at codesigning.azure.net
# 2. Create certificate profile "production"
# 3. Note tenant ID, client ID, account name
```

**Expert catches**: Novices often skip the app-specific password step or try to use their Apple ID password directly. Expert immediately generates app-specific password at appleid.apple.com.

**Step 2 - Auto-Updater Keys**:
```bash
# Generate signing keypair
cargo tauri signer generate -w ~/.tauri/devtools.key

# Output shows:
# Private key: ~/.tauri/devtools.key (keep secret!)
# Public key: dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWdu... (embed in app)
```

**Expert catches**: The public key goes in `tauri.conf.json` under `plugins.updater.pubkey`, NOT as a file. Novices often try to reference a pubkey file path.

**Step 3 - CI Configuration**:
```yaml
name: Release
on:
  push:
    tags: ["v*"]

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: macos-latest
            target: aarch64-apple-darwin
          - os: windows-latest
            target: x86_64-pc-windows-msvc
    runs-on: ${{ matrix.os }}
    steps:
      - uses: tauri-apps/tauri-action@v0
        env:
          # Apple secrets
          APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
          # Windows secrets  
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
          AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
          # Update signing
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
        with:
          tagName: v__VERSION__
          releaseName: "DevTools v__VERSION__"
```

**Expert catches**: The `APPLE_SIGNING_IDENTITY` must match the certificate name exactly, including the team ID in parentheses. Novices often forget the team ID or get the format wrong.

**Decision point navigated**: Since this is a GitHub Actions setup with Windows distribution, expert chose Azure Trusted Signing over EV certificate for cost and simplicity. For a GitLab CI setup, would have chosen traditional EV cert.

**Step 4 - Testing Update Flow**:
```typescript
// In the app frontend
import { check } from "@tauri-apps/plugin-updater";

async function testUpdate() {
  console.log("Checking for updates...");
  const update = await check();
  
  if (update) {
    console.log(`Found update: ${update.version}`);
    // Expert validates signature is checked automatically by Tauri
    await update.downloadAndInstall();
  }
}
```

**Expert catches**: The updater automatically validates signatures using the embedded public key. Novices often try to add manual signature verification, which is redundant and error-prone.

## Reference Files

- `diagrams/01_flowchart_decision-points.md` — Mermaid flowchart routing requests through scope validation, constraint assessment, and pattern selection. **Read when** unsure whether a request fits this skill or which distribution path to follow.

## Quality Gates

**Pre-release validation checklist:**

- [ ] macOS app signed with Developer ID Application certificate (verify: `codesign -dv MyApp.app`)
- [ ] macOS app notarization completed and ticket stapled (verify: `spctl --assess --type exec -v MyApp.app`)
- [ ] Windows executable signed with EV or Azure Trusted Signing (verify: `signtool verify /pa MyApp.exe`)
- [ ] SmartScreen reputation check passed (test on clean Windows VM)
- [ ] Auto-updater endpoint returns valid JSON with correct signatures
- [ ] Update signing keys generated and private key secured in CI secrets
- [ ] All target architectures built and tested (x86_64, aarch64 for macOS)
- [ ] Package manager manifests updated with correct SHA256 hashes
- [ ] Release artifacts uploaded to GitHub releases with proper naming
- [ ] CI pipeline completes without certificate warnings or errors
- [ ] Rollback test: previous version can still check for and install updates
- [ ] Offline test: notarized macOS app launches without internet connection

## NOT-FOR Boundaries

**Do NOT use this skill for:**

- **Library crate publishing** → Use `cargo publish` and crates.io documentation instead
- **Web application deployment** → Use `devops-automator` skill for containerized deployment
- **Mobile app distribution** → Use platform-specific mobile deployment skills (iOS App Store, Google Play)
- **Internal enterprise distribution without signing** → This skill assumes public distribution requiring code signing
- **Building the application itself** → Use `rust-tauri-development` skill for app development and local building
- **Backend service deployment** → Use infrastructure deployment skills for server applications
- **Cross-compilation troubleshooting** → Use native runners; cross-compilation not recommended for desktop apps with platform-specific dependencies

**Delegate to other skills:**
- For CI/CD infrastructure setup → `devops-automator`
- For Tauri app development → `rust-tauri-development` 
- For cross-platform desktop architecture → `cross-platform-desktop`

<!-- BEGIN BUNDLE INDEX (auto: index_references.py) -->

## Skill Bundle Index

*Every file in this skill, and when to open it. Auto-generated; run `scripts/index_references.py --fix`.*

**root**
- [`CHANGELOG.md`](CHANGELOG.md) — Rust App Distribution — Changelog — - Normalized frontmatter into the canonical metadata-based repo shape - Added or refreshed repo-local provenance metadata - Recorded this au
- [`affordance-scorecard.json`](affordance-scorecard.json) — affordance scorecard (data/schema)

**`diagrams/`**
- [`diagrams/01_flowchart_decision-points.md`](diagrams/01_flowchart_decision-points.md) — Diagram 1: flowchart

<!-- END BUNDLE INDEX -->

Files in this skill

  • CHANGELOG.md1.8 KB
  • SKILL.md14.4 KB
  • affordance-scorecard.json1.1 KB
  • diagrams/01_flowchart_decision-points.md597 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…