Skip to content

🧊 Lightweight macOS menu bar app for automated cold backups to AWS S3 Glacier Deep Archive

License

Notifications You must be signed in to change notification settings

lydakis/icevault

Repository files navigation

IceVault 🧊

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.

Features

  • Glacier Deep Archive uploads (DEEP_ARCHIVE storage 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

Requirements

  • macOS 14+ (Sonoma)
  • AWS account with S3 access
  • Xcode 16+ (for Xcode workflow)
  • Swift 6.1+ (for SwiftPM workflow)

Build

swift build --disable-sandbox

Run

swift run IceVault

Headless backup mode (used by LaunchAgent):

swift run IceVault --backup

Quick Install (.app)

./scripts/build-app.sh && open build/IceVault.app

Install via Homebrew

brew install --cask lydakis/icevault/icevault

Upgrade:

brew upgrade --cask lydakis/icevault/icevault

Uninstall:

brew uninstall --cask icevault

Build DMG

./scripts/build-app.sh --dmg

Output:

  • build/IceVault.app
  • build/IceVault-<version>-macos-<arch>.dmg

Release-oriented options:

./scripts/build-app.sh --dmg --version 0.1.0 --arch arm64 --output-dir dist

Manual Install

cp -R build/IceVault.app /Applications/
open /Applications/IceVault.app

Least-Privilege IAM Policy

Replace 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/*"
    }
  ]
}

AWS Credentials Setup

IceVault credential resolution order is:

  1. Keychain (credentials saved from IceVault Settings)
  2. ~/.aws/credentials ([default] profile)
  3. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY env vars

Region resolution uses:

  1. Region set in IceVault Settings
  2. ~/.aws/config ([default] profile region)
  3. 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.

Option A: aws configure

aws configure

This writes:

  • ~/.aws/credentials
  • ~/.aws/config

Option B: Manual files

~/.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-1

Option C: Environment variables

export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY
export AWS_REGION=us-east-1

Scheduled Backups

IceVault 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.

Releases + Homebrew

Tagging v* on main triggers .github/workflows/release.yml, which:

  1. Builds DMGs for arm64 and x86_64
  2. Signs the app with Developer ID and notarizes/staples app + DMG
  3. Publishes both assets to the GitHub Release
  4. Updates lydakis/homebrew-icevault with a new Casks/icevault.rb

Required secrets in lydakis/icevault:

  • APPLE_DEVELOPER_ID_CERTIFICATE_P12_BASE64
  • APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD
  • APPLE_DEVELOPER_ID_APPLICATION
  • APP_STORE_CONNECT_API_KEY_P8
  • APP_STORE_CONNECT_KEY_ID
  • APP_STORE_CONNECT_ISSUER_ID
  • GORELEASER_TOKEN (preferred), or HOMEBREW_TAP_GITHUB_TOKEN

Detailed release steps: docs/release.md

Screenshots

Screenshots will be added for:

  • Menu bar status view
  • Settings view (credentials + scheduling)
  • Backup history view

Contributing

  1. Fork the repo.
  2. Create a feature branch.
  3. Make focused changes with clear commit messages.
  4. Run swift build --disable-sandbox before opening a PR.
  5. Open a pull request with a short summary and testing notes.

License

MIT

About

🧊 Lightweight macOS menu bar app for automated cold backups to AWS S3 Glacier Deep Archive

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors