Signing & Verification¶
Secure your FlavorPack packages with Ed25519 digital signatures for authenticity and integrity.
๐ค AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
Overview¶
FlavorPack uses Ed25519 digital signatures to ensure packages haven't been tampered with and come from trusted sources. This guide covers key generation, package signing, verification, and best practices for secure distribution.
Quick Start¶
Generate Keys¶
# Generate a new Ed25519 key pair
flavor keygen --out-dir keys
# This creates:
# - keys/flavor-private.key (private key - keep secret!)
# - keys/flavor-public.key (public key - distribute freely)
Sign Package¶
# Sign during build
flavor pack --manifest pyproject.toml --private-key keys/flavor-private.key --public-key keys/flavor-public.key
# Package is now signed and can be verified
Verify Package¶
Public Key Verification
The verify command automatically uses the public key embedded in the package. External key verification is planned for a future release.
Key Management¶
Key Generation Options¶
1. Random Keys (Recommended for Production)¶
Generate cryptographically secure random keys:
# Generate with default settings (creates keys/ directory)
flavor keygen
# Specify custom output directory
flavor keygen --out-dir ~/.flavor/keys
2. Using Existing Keys¶
Use existing Ed25519 key files:
# Keys must be in PEM format
flavor pack --manifest pyproject.toml \
--private-key /path/to/flavor-private.key \
--public-key /path/to/flavor-public.key
Note: Keys must be Ed25519 format in PEM encoding. The private key file should be 32 bytes (raw seed) or PEM-encoded Ed25519 private key.
Key Storage Best Practices¶
Development¶
# Store in home directory
mkdir -p ~/.flavor/keys
chmod 700 ~/.flavor/keys
flavor keygen --out-dir ~/.flavor/keys
chmod 600 ~/.flavor/keys/flavor-private.key
Production¶
-
Encrypted Storage
-
Secret Management
- Store private key in secret manager (AWS Secrets Manager, HashiCorp Vault, etc.)
- Retrieve at build time via environment variables or secret injection
- Never commit private keys to version control
CI/CD¶
# GitHub Actions with secrets
- name: Sign package
env:
FLAVOR_KEY_SEED: ${{ secrets.SIGNING_SEED }}
run: |
flavor pack --manifest pyproject.toml --key-seed "$FLAVOR_KEY_SEED"
# GitLab CI with protected variables
sign:
script:
- flavor pack --manifest pyproject.toml --key-seed "$CI_SIGNING_SEED"
only:
- tags
Key Rotation¶
Implement regular key rotation by rebuilding packages with new keys:
# Generate new key
flavor keygen --out-dir keys/2024-01
# Rebuild packages with new key
for manifest in projects/*/pyproject.toml; do
flavor pack --manifest "$manifest" \
--private-key keys/2024-01/flavor-private.key \
--public-key keys/2024-01/flavor-public.key
done
# Archive old key
mv keys/2023-12 keys/archive/
Signing Process¶
How Signing Works¶
- Metadata Hash: Package metadata is serialized and hashed with SHA-256
- Digital Signature: Hash is signed with Ed25519 private key
- Embedding: Public key and signature are embedded in package index block
- Verification: Signature can be verified using embedded or external public key
Build-Time Signing¶
All signing happens during package build with flavor pack:
# Basic signing with key files
flavor pack --manifest pyproject.toml \
--private-key keys/flavor-private.key \
--public-key keys/flavor-public.key
# With deterministic seed (for reproducible builds)
flavor pack --manifest pyproject.toml --key-seed "secret-seed"
# Signing is automatic - no separate sign command needed
No Post-Build Signing
FlavorPack does not support signing packages after they've been built. Signing happens only during flavor pack. To re-sign a package, rebuild it with new keys.
Batch Building with Signing¶
Build and sign multiple packages:
#!/bin/bash
# build-and-sign-all.sh
PRIVATE_KEY="$1"
PUBLIC_KEY="$2"
for manifest in projects/*/pyproject.toml; do
echo "Building and signing $manifest..."
flavor pack --manifest "$manifest" \
--private-key "$PRIVATE_KEY" \
--public-key "$PUBLIC_KEY"
done
Verification¶
Automatic Verification¶
Packages are automatically verified when executed:
# Launcher verifies signature before extraction
./myapp.psp
# Disable verification (DANGEROUS - development only!)
FLAVOR_VALIDATION=none ./myapp.psp
Manual Verification¶
Basic Verification¶
# Verify with embedded public key
flavor verify package.psp
# Output:
# โ
Signature valid
# Package: myapp v1.0.0
# Signed by: SHA256:abc123...
Deep Verification¶
Planned Feature: Advanced verification modes are planned for a future release. Currently, the
verifycommand performs comprehensive verification of all components.
# Verify all components (standard verification)
flavor verify package.psp
# Output:
# โ
Index block valid
# โ
Metadata signature valid
# โ
All slot checksums valid
# โ
Package integrity confirmed
Verification with External Key¶
๐ Planned Feature
External key verification is planned for a future release. Currently, verification uses the public key embedded in the package.
Current verification:
Planned verification (future release):
# Verify against external trusted key (not yet implemented)
flavor verify package.psp --public-key trusted.pub
flavor verify package.psp --trusted-keys keys/trusted/
Programmatic Verification¶
from pathlib import Path
from flavor.package import verify_package
# Verify package
result = verify_package(Path("package.psp"))
if result["signature_valid"]:
print("โ
Package signature verified")
else:
print("โ Invalid signature!")
Trust Models¶
1. Self-Signed (Default)¶
Package contains its own public key:
Use Cases: - Internal distribution - Development packages - Personal projects
Verification:
2. Pre-Shared Keys¶
๐ Planned Feature
Pre-shared key verification with external key management is planned for a future release.
Distribute public keys separately:
# Planned configuration format
[tool.flavor.security]
trust_model = "pre-shared"
require_known_key = true
Planned Distribution Methods:
# Via secure channel
scp public.pem user@server:/etc/flavor/trusted-keys/
# Via configuration management
ansible-playbook deploy-keys.yml
# Via package manager
apt-get install myapp-signing-keys
Current Verification:
Planned Verification:
# Future: Verify against trusted keys
# flavor verify package.psp --trusted-keys /etc/flavor/trusted-keys/
3. Web of Trust (Future)¶
Planned Feature
Multiple signatures from trusted parties is planned for a future release.
Planned workflow:
4. Certificate Authority (Future)¶
X.509 certificate chains:
Key Distribution¶
Public Key Format¶
FlavorPack generates keys in PEM format:
# Generate keys
flavor keygen --out-dir keys
# Public key is in PEM format
cat keys/flavor-public.key
# -----BEGIN PUBLIC KEY-----
# ...
# -----END PUBLIC KEY-----
Key Format Conversion
For other formats (SSH, JWK, etc.), use standard tools like ssh-keygen or openssl to convert the PEM-formatted public key.
Distribution Channels¶
1. Package Metadata¶
The public key is automatically embedded in every signed package's index block. Recipients can extract it for verification:
2. Key Servers¶
# Upload to key server
curl -X POST https://keys.example.com/upload \
-F "[email protected]" \
-F "[email protected]"
3. DNS Records¶
4. Version Control¶
# Commit public keys (never private!)
git add keys/public/*.pem
git commit -m "Add signing public keys"
Security Best Practices¶
Do's โ ¶
-
Generate keys on secure systems
-
Use unique keys per environment
-
Rotate keys regularly
-
Verify packages before distribution
-
Log signature verification
Don'ts โ¶
-
Never commit private keys
-
Never share private keys
-
Never use weak seeds
-
Never ignore verification failures
Troubleshooting¶
Common Issues¶
"Private key not found"¶
# Check file exists and permissions
ls -la private.pem
# Should show: -rw------- (600)
# Fix permissions
chmod 600 private.pem
"Invalid signature"¶
# Verify package
flavor verify package.psp
# Check package integrity with checksum
sha256sum package.psp
# If corrupted, rebuild the package with correct keys
flavor pack --manifest pyproject.toml \
--private-key keys/flavor-private.key \
--public-key keys/flavor-public.key
"Key format not recognized"¶
# Convert to PEM format
openssl pkey -in key.der -inform DER -out key.pem
# Verify key type
openssl pkey -in key.pem -text | head -1
# Should show: "ED25519 Private-Key"
Debugging¶
# Verbose verification
FOUNDATION_LOG_LEVEL=debug flavor verify package.psp
# Inspect signature details
flavor inspect package.psp
# The inspect command shows:
# - Package signature status
# - Embedded public key (first 16 bytes)
# - Format version and metadata
Advanced Topics (Future Features)¶
The following features are planned for future releases:
Multi-Signature Packages (Planned)¶
Future Feature
Support for multiple signatures per package is under development.
Planned API:
Threshold Signatures (Planned)¶
Future Feature
Threshold signature schemes (N-of-M signatures required) are planned.
Planned manifest format:
Hardware Token Integration (Planned)¶
Notarization (Platform-Specific)¶
Platform-Specific
For macOS code signing and notarization, use Apple's standard tools after building:
# Build package
flavor pack --manifest pyproject.toml --output myapp.psp
# Sign with codesign (macOS only)
codesign --sign "Developer ID" myapp.psp
# Notarize with Apple (macOS only)
xcrun notarytool submit myapp.psp \
--apple-id "[email protected]" \
--team-id "TEAMID"
Related Documentation¶
- Cryptographic Specification - Technical details
- Security Model - Security architecture
- Package Verification - API reference
- Troubleshooting - Common issues