> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibetunnel.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Sparkle keys

# Sparkle Key Management Guide

This guide covers the management of EdDSA keys used for signing VibeTunnel updates with the Sparkle framework.

## Overview

VibeTunnel uses Sparkle's EdDSA (Ed25519) signatures for secure software updates. This system requires:

* A **private key** (kept secret) for signing updates
* A **public key** (distributed with the app) for verifying signatures

## Key Locations

### Public Key

* **Location**: `VibeTunnel/sparkle-public-ed-key.txt`
* **Status**: Committed to repository
* **Usage**: Embedded in app via `SUPublicEDKey` in Info.plist
* **Current Value**: `AGCY8w5vHirVfGGDGc8Szc5iuOqupZSh9pMj/Qs67XI=`

### Private Key

* **Location**: `private/sparkle_private_key`
* **Status**: NOT in version control (in .gitignore)
* **Usage**: Required for signing updates during release
* **Format**: Base64-encoded key data (no comments or headers)

## Initial Setup

### For New Team Members

1. **Request Access**
   ```bash theme={null}
   # Contact team lead for secure key transfer
   # Keys are stored in: Dropbox/Backup/Sparkle-VibeTunnel/
   ```

2. **Install Private Key**
   ```bash theme={null}
   # Create private directory
   mkdir -p private

   # Add key file (get content from secure backup)
   echo "BASE64_PRIVATE_KEY_HERE" > private/sparkle_private_key

   # Verify it's ignored by git
   git status  # Should not show private/
   ```

3. **Verify Setup**
   ```bash theme={null}
   # Test signing with your key
   ./build/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update \
     any_file.dmg \
     -f private/sparkle_private_key
   ```

### For New Projects

1. **Generate New Keys**
   ```bash theme={null}
   # Build Sparkle tools first
   ./scripts/build.sh

   # Generate new key pair
   ./build/SourcePackages/artifacts/sparkle/Sparkle/bin/generate_keys
   ```

2. **Save Keys**
   ```bash theme={null}
   # Copy displayed keys:
   # Private key: [base64 string]
   # Public key: [base64 string]

   # Save private key
   mkdir -p private
   echo "PRIVATE_KEY_BASE64" > private/sparkle_private_key

   # Save public key
   echo "PUBLIC_KEY_BASE64" > VibeTunnel/sparkle-public-ed-key.txt
   ```

3. **Update App Configuration**
   * Add public key to Info.plist under `SUPublicEDKey`
   * Commit public key file to repository

## Key Security

### Best Practices

1. **Never Commit Private Keys**
   * Private directory is in .gitignore
   * Double-check before committing

2. **Secure Backup**
   * Store in encrypted location
   * Use password manager or secure cloud storage
   * Keep multiple secure backups

3. **Limited Access**
   * Only release managers need private key
   * Use secure channels for key transfer
   * Rotate keys if compromised

4. **Key Format**
   * Private key file must contain ONLY the base64 key
   * No comments, headers, or extra whitespace
   * Single line of base64 data

### Example Private Key Format

```
SMYPxE98bJ5iLdHTLHTqGKZNFcZLgrT5Hyjh79h3TaU=
```

## Troubleshooting

### "EdDSA signature does not match" Error

**Cause**: Wrong private key or key format issues

**Solution**:

1. Verify private key matches public key
2. Check key file has no extra characters
3. Regenerate appcast with correct key

### "Failed to decode base64 encoded key data"

**Cause**: Private key file contains comments or headers

**Solution**:

```bash theme={null}
# Extract just the key
grep -v '^#' your_key_backup.txt | grep -v '^$' > private/sparkle_private_key
```

### Testing Key Pair Match

```bash theme={null}
# Sign a test file
echo "test" > test.txt
./build/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update \
  test.txt \
  -f private/sparkle_private_key

# The signature should generate successfully
# Compare with production signatures to verify
```

## Key Rotation

If keys need to be rotated:

1. **Generate New Keys**
   ```bash theme={null}
   ./build/SourcePackages/artifacts/sparkle/Sparkle/bin/generate_keys
   ```

2. **Update App**
   * Change `SUPublicEDKey` in Info.plist
   * Update `sparkle-public-ed-key.txt`
   * Release new version with new public key

3. **Transition Period**
   * Keep old private key for emergency updates
   * Sign new updates with new key
   * After all users update, retire old key

## Integration with Release Process

The release scripts automatically use the private key:

1. **generate-appcast.sh**
   * Expects key at `private/sparkle_private_key`
   * Fails if key missing or invalid
   * Signs all DMG files in releases

2. **release.sh**
   * Calls generate-appcast.sh after creating DMG
   * Ensures signatures are created before pushing

## Recovery Procedures

### Lost Private Key

If private key is lost:

1. Generate new key pair
2. Update app with new public key
3. Release update signed with old key (if possible)
4. All future updates use new key

### Compromised Private Key

If private key is compromised:

1. Generate new key pair immediately
2. Release security update with new public key
3. Notify users of security update
4. Revoke compromised key (document publicly)

## Verification Commands

### Verify Current Setup

```bash theme={null}
# Check public key in app
/usr/libexec/PlistBuddy -c "Print :SUPublicEDKey" \
  build/Build/Products/Release/VibeTunnel.app/Contents/Info.plist

# Check private key exists
ls -la private/sparkle_private_key

# Test signing
./scripts/generate-appcast.sh --dry-run
```

### Verify Release Signatures

```bash theme={null}
# Check signature in appcast
grep "sparkle:edSignature" appcast-prerelease.xml

# Manually verify a DMG
./build/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update \
  build/VibeTunnel-1.0.0.dmg \
  -f private/sparkle_private_key
```

## Additional Resources

* [Sparkle Documentation](https://sparkle-project.org/documentation/)
* [EdDSA on Wikipedia](https://en.wikipedia.org/wiki/EdDSA)
* [Ed25519 Key Security](https://ed25519.cr.yp.to/)

***

For questions about key management, contact the release team lead.
