A lightweight macOS menu bar app for automated cold backups to AWS S3 Glacier Deep Archive.
IceVault focuses on low-cost archival backups with a native SwiftUI menu bar experience.
- Glacier Deep Archive uploads (
DEEP_ARCHIVEstorage class) - Incremental sync using a local SQLite inventory
- Multipart uploads for large files (>100 MB)
- Resume-safe backup jobs with history
- Credential auto-detection (
Keychain->~/.aws/credentials-> env vars) - Optional scheduled backups via LaunchAgent
- macOS 14+ (Sonoma)
- AWS account with S3 access
- Xcode 16+ (for Xcode workflow)
- Swift 6.1+ (for SwiftPM workflow)
swift build --disable-sandboxswift run IceVaultHeadless backup mode (used by LaunchAgent):
swift run IceVault --backup./scripts/build-app.sh && open build/IceVault.appbrew install --cask lydakis/icevault/icevaultUpgrade:
brew upgrade --cask lydakis/icevault/icevaultUninstall:
brew uninstall --cask icevault./scripts/build-app.sh --dmgOutput:
build/IceVault.appbuild/IceVault-<version>-macos-<arch>.dmg
Release-oriented options:
./scripts/build-app.sh --dmg --version 0.1.0 --arch arm64 --output-dir distcp -R build/IceVault.app /Applications/
open /Applications/IceVault.appReplace YOUR_BUCKET_NAME with your bucket. This policy scopes access to one bucket and only upload-related actions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IceVaultBucketAccess",
"Effect": "Allow",
"Action": [
"s3:HeadBucket"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
},
{
"Sid": "IceVaultObjectUploadAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:CreateMultipartUpload",
"s3:UploadPart",
"s3:CompleteMultipartUpload",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
}
]
}IceVault credential resolution order is:
- Keychain (credentials saved from IceVault Settings)
~/.aws/credentials([default]profile)AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEYenv vars
Region resolution uses:
- Region set in IceVault Settings
~/.aws/config([default]profile region)AWS_REGION/AWS_DEFAULT_REGION
Recommended default for unattended backups:
- Use a dedicated IAM user (programmatic access only) with least-privilege bucket policy.
- Store access key + secret in IceVault (Keychain-backed).
- Use SSO profiles for interactive/admin workflows, not long-running unattended jobs.
aws configureThis writes:
~/.aws/credentials~/.aws/config
~/.aws/credentials
[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY~/.aws/config
[default]
region = us-east-1export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY
export AWS_REGION=us-east-1IceVault can install a LaunchAgent at:
~/Library/LaunchAgents/com.icevault.backup.plist
The agent runs IceVault with:
--backup
Supported intervals:
- Daily
- Weekly
- Custom (every N hours)
Configure this in the Settings UI under Scheduling.
Tagging v* on main triggers .github/workflows/release.yml, which:
- Builds DMGs for
arm64andx86_64 - Signs the app with Developer ID and notarizes/staples app + DMG
- Publishes both assets to the GitHub Release
- Updates
lydakis/homebrew-icevaultwith a newCasks/icevault.rb
Required secrets in lydakis/icevault:
APPLE_DEVELOPER_ID_CERTIFICATE_P12_BASE64APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORDAPPLE_DEVELOPER_ID_APPLICATIONAPP_STORE_CONNECT_API_KEY_P8APP_STORE_CONNECT_KEY_IDAPP_STORE_CONNECT_ISSUER_IDGORELEASER_TOKEN(preferred), orHOMEBREW_TAP_GITHUB_TOKEN
Detailed release steps: docs/release.md
Screenshots will be added for:
- Menu bar status view
- Settings view (credentials + scheduling)
- Backup history view
- Fork the repo.
- Create a feature branch.
- Make focused changes with clear commit messages.
- Run
swift build --disable-sandboxbefore opening a PR. - Open a pull request with a short summary and testing notes.
MIT