Skip to content

Secure, encrypted file vault backed by GitHub. End-to-end encryption, zero-knowledge architecture, free and open-source.

Notifications You must be signed in to change notification settings

zephyrus-development/zephyrus-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚠️ For detailed technical architecture, cryptographic design, and security analysis, please refer to the Whitepaper.


Zephyrus CLI

A secure, encrypted file vault backed by GitHub. Store your sensitive files with confidence using end-to-end encryption and git-based version control.

What is Zephyrus CLI?

Zephyrus CLI is a command-line tool that transforms your GitHub repository into a private, encrypted file vault. Your files are encrypted locally before being uploaded, ensuring that even if your GitHub repository is compromised, your data remains secure.

Want an interactive demo of our sharing capabilities, click here to download a demo txt file, or click the link: https://zep.ftp.sh/shared/#zephyrus-development:nOsiH8:password:RG93bmxvYWRNZS50eHQ=

Key Features:

  • 🔐 End-to-End Encryption: Files are encrypted with AES-256-GCM before leaving your computer
  • 🔑 Per-File Encryption Keys: Each file has its own unique encryption key for secure sharing
  • ☁️ GitHub-Backed Storage: Uses a private GitHub repository as distributed storage
  • 🗂️ Hierarchical Organization: Create folders and organize files with full path support
  • 🔍 Search Functionality: Quickly find files by name or path
  • 📝 Version Control: Full git history of all vault operations with customizable commit messages
  • 💻 Cross-Platform: Works on Windows, macOS, and Linux
  • 🎯 Stateless Mode: Use with -u flag to authenticate without persistent sessions
  • 🔄 Interactive Shell (REPL):
    • Multiple commands without re-authentication
    • TAB completion for file paths
    • Local filesystem access via lls/ldir commands
    • Real-time command history
  • 📤 Secure File Sharing: Share individual files without exposing your entire vault
    • Generate shareable links with unique encryption keys
    • Share via command-line or browser-based download page
    • Recipients decrypt files in their browser (zero-knowledge sharing)
    • Search and manage shared files by name
    • Easy revocation of access
  • ⚙️ Configurable Settings: Customize commit attribution, hash lengths, and messages
  • 📊 Vault Information: Get statistics and metadata about files and vault size
  • 📖 File Preview: Read file contents directly without download
  • ⏱️ Progress Indicators: Visual feedback during all vault operations

Prerequisites

Before you can use Zephyrus CLI, you'll need:

  1. A GitHub Account
  2. A Private Key for GitHub: SSH key for authentication (e.g., id_ed25519)
  3. An Empty GitHub Repository: Create a repository named .zephyrus in your GitHub account
  4. Zephyrus CLI Binary: Download from releases

Installation

Install with Scoop (Windows)

If you have Scoop installed, the easiest way to install Zephyrus CLI is:

scoop bucket add zephyrus https://github.com/zephyrus-development/scoop-zephyrus
scoop install zephyrus/zep

To update:

scoop update
scoop update zep

To uninstall:

scoop uninstall zep

Download Binary

  1. Visit the Zephyrus CLI Releases Page
  2. Download the latest release for your operating system:
    • Windows: zep.exe
    • macOS: Please download and compile from source.
    • Linux: Please download and compile from source, linux release coming soon.
  3. Make the binary executable (macOS/Linux):
    chmod +x zep-*
  4. Optionally, add to your PATH for system-wide access

Setup Your Vault

Before you can use Zephyrus CLI, you must set up a deploy key on the .zephyrus repository:

  1. Generate an SSH keypair using either:

    • ssh-keygen command (most secure)
    • Online tool like this one
  2. Add the public key to your .zephyrus repository's deploy key settings

  3. Important: Enable read and write permissions for the deploy key (required for uploading and managing files)

Then to start using Zephyrus CLI, initialize your vault:

./zep setup <github-username> <path-to-ssh--private-key>

Example:

./zep setup Auchrio ./private_key.txt

When prompted:

  • Enter your GitHub username (if not provided as argument)
  • Provide the path to your SSH private key
  • Create a vault password (you'll use this to encrypt your GitHub SSH key)

What happens during setup:

  1. Verifies your .zephyrus repository exists on GitHub
  2. Reads your SSH private key from disk
  3. Encrypts the key with your vault password
  4. Pushes the encrypted key to .config/key in your vault repository

⚠️ Important: Your vault password is never stored. You must remember it becasue nobody can recover it for you.

Getting Started

Interactive Mode (REPL)

Start the interactive shell:

./zep

You'll be prompted to enter your username and password. Once authenticated, you can run commands without re-entering credentials:

=== Zephyrus Interactive Shell ===
Username: myusername
Password: ••••••••••
✔ Welcome, myusername. Session Active.
Type 'help' for commands or 'exit' to quit.
(Press TAB to autocomplete file paths)

zep> upload ./document.pdf documents/report.pdf
✔ Upload successful.

zep> ls documents
NAME          TYPE    STORAGE ID
----          ----    ----------
report.pdf    [FILE]  a3f2e1c9d4b6f8e2

zep> lls Documents
file1.txt
file2.pdf

zep> exit

REPL Features:

  • TAB Completion: Press TAB to cycle through file path suggestions
  • Local File Access: Use lls/ldir to browse local filesystem without exiting shell
  • Persistent Session: Stay authenticated across multiple commands
  • Command History: Shell remembers previous commands

Command Line Mode

Run commands directly without entering the shell:

# Upload a file
./zep upload ./document.pdf documents/report.pdf

# List files
./zep ls documents

# Download a file
./zep download documents/report.pdf ./report.pdf

# Exit

Stateless Mode

If you haven't run connect, you can use any command with the -u flag to authenticate on-the-fly:

./zep upload -u myusername ./document.pdf documents/report.pdf

You'll be prompted for your vault password. This doesn't create a persistent session.

Secure File Sharing

Zephyrus makes it easy to securely share individual files with others without exposing your entire vault.

How It Works

  1. Generate a Share Link: Create a unique, encrypted share link for any file
  2. Each file gets its own encryption key: Recipients use a separate password to decrypt
  3. Browser-based decryption: Files are decrypted in the recipient's browser (zero-knowledge)
  4. No vault access needed: Recipients don't need a Zephyrus account or access to your vault

Share a File

# Enter interactive mode and share
zep> share documents/report.pdf
Enter Share Password (recipients will use this to decrypt): mysharepass123

✔ File shared successfully!
Filename: report.pdf

Share this string with recipient:
Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg==

Web Share Link:
  https://zep.ftp.sh/shared/#Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg==

Recipient can download with:
  zep download _ output.file --shared "Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg=="

Or read with:
  zep read _ --shared "Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg=="

Recipient Options

Recipients can access shared files in 3 ways:

  1. Web Browser (Easiest): Click the share link and download securely in browser

    https://zep.ftp.sh/shared/#Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg==
    
  2. CLI Download: Use the Zephyrus CLI to download

    zep download _ output.pdf --shared "Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg=="
  3. CLI Read: Display file content directly (no save)

    zep read _ --shared "Auchrio:72cTWg:mysharepass123:cmVwb3J0LnBkZg=="

Manage Shared Files

View all shared files and their metadata:

zep shared ls

Get detailed info and regenerate share link:

zep shared info 72cTWg

Revoke a share (stop allowing access):

zep shared rm 72cTWg

Advanced Features

Directory Upload & Download

Zephyrus supports uploading and downloading entire directories recursively, perfect for backing up projects or bulk file operations.

Upload Directory:

# Upload entire directory structure
./zep upload ./my-documents vault/backups/documents

# This uploads all files and subdirectories while preserving structure

Download Directory:

# Download entire directory from vault
./zep download vault/backups/documents ./restored-documents

# All files and folder structure recreated locally

Features:

  • ✅ Preserves full directory structure
  • ✅ Recursively processes nested folders
  • ✅ Each file encrypted independently
  • ✅ Atomic operation (all or nothing)
  • ✅ Progress tracking for large directories

See docs/UPLOAD.md and docs/DOWNLOAD.md for detailed information.

Transfer Vault Between Accounts

Migrate your entire vault to a different GitHub account with a single command.

Transfer Vault:

# Migrate all files to different GitHub account
./zep transfer-vault source-username dest-username

What It Does:

  1. Authenticates with source vault (old account)
  2. Authenticates with destination vault (new account)
  3. Fetches all files from source vault
  4. Decrypts with source password
  5. Re-encrypts with destination password
  6. Uploads to destination vault

Example:

./zep transfer-vault old-github-user new-github-user
# Password for old-github-user: ••••••••••
# Password for new-github-user: ••••••••••
# Confirm transfer: [y/N] y

# Processing: 100%
# ✔ Transfer complete: 42 files migrated

Use Cases:

  • Switching to a new GitHub account
  • Consolidating multiple accounts
  • Transferring vault to team member
  • Account recovery

See docs/TRANSFER.md for complete documentation.

Password Reset

Change your vault password and re-encrypt all vault data with the new password.

Reset Password:

# Reset vault password (will re-encrypt all vault data)
./zep reset-password

Interactive Process:

Enter current password for verification: ••••••••••
Enter new password: ••••••••••
Confirm new password: ••••••••••

Processing vault re-encryption...
[1/5] Validating password...
[2/5] Updating master key...
[3/5] Re-encrypting all file keys...
[4/5] Re-encrypting vault components...
[5/5] Uploading changes to GitHub...

✔ Password successfully reset

Key Points:

  • ⚠️ Cannot be reverted (new password is permanent)
  • ✅ Every file in vault re-encrypted with new key
  • ✅ All file encryption keys updated
  • ✅ Vault structure remains the same
  • ✅ All files remain accessible with new password

See docs/AUTH.md for security considerations and detailed information.

Web Interface

Access your vault through a modern web browser without installing CLI tools.

Features:

  • 🌐 Browser-based file access and download
  • 🔐 Client-side decryption (zero-knowledge)
  • 📁 File browsing and navigation
  • 🔗 Secure shareable file links
  • 📱 Mobile and tablet support
  • 🔑 GitHub OAuth authentication support

Access Your Vault:

https://<your-github-username>.github.io/zephyrus

Capabilities:

  • View and download files directly in browser
  • Share individual files with unique encryption
  • Browse vault folder structure
  • Mobile-friendly interface
  • No CLI installation required

See docs/WEB.md for complete web interface documentation.

Icons & Branding

Your Zephyrus web interface includes professional icons and branding assets:

Included Icons:

  • 🎨 Favicon (multiple sizes: 16px, 32px, 96px)
  • 📱 Apple device icons (9 different sizes: 57px-180px)
  • 🤖 Android icon (192px)
  • 🪟 Windows tile icon (144px)
  • 🎯 Manifest.json for PWA support
  • 🎨 Custom brand color (Purple #7431ff)
  • 🌐 Open Graph meta tags for social media

Location: Images and icons are stored in pages/images/ directory and automatically referenced by all web pages.


Command Reference

setup - Initialize Your Vault

Sets up a new Zephyrus vault by encrypting and storing your GitHub SSH key.

Usage:

./zep setup [username] [key-path]

Arguments:

  • username (optional): Your GitHub username
  • key-path (optional): Path to your SSH private key (e.g., ~/.ssh/id_ed25519)

Interactive Prompts (if arguments not provided):

  • GitHub Username
  • SSH Key Path
  • Vault Password (to encrypt your key)

Example:

./zep setup myusername ~/.ssh/id_ed25519
# Or interactively:
./zep setup

Prerequisites:

  • Repository named .zephyrus must exist on your GitHub account
  • SSH key must exist at the specified path
  • SSH key must have access to GitHub

Note: This command must be run once before using other vault operations.


connect - Create a Persistent Session

Authenticates and caches your vault index locally in zephyrus.conf. Subsequent commands won't require re-authentication.

Usage:

./zep connect [username]

Aliases: conn, login, auth, signin, con, cn

Arguments:

  • username (optional): Your GitHub username

Interactive Prompts (if username not provided):

  • Username
  • Vault Password

Example:

./zep connect myusername
# Password: ••••••••••
# ✔ Connected.

./zep upload ./file.pdf documents/file.pdf
# Uses cached session - no password prompt

When to Use:

  • You're running multiple commands in sequence
  • You want to avoid entering your password repeatedly
  • You're working on a secure machine where storing zephyrus.conf is safe

Note: Creates a file called zephyrus.conf in the current directory containing your cached index.


upload - Upload a File

Encrypts and uploads a file from your local filesystem to the vault.

Usage:

./zep upload <local-path> <vault-path>

Aliases: up, u, add

Arguments:

  • local-path (required): Path to the file on your computer
  • vault-path (required): Destination path in the vault (e.g., documents/report.pdf)

Features:

  • Automatically creates intermediate folders if they don't exist
  • Updates existing files (overwrites content while keeping storage ID)
  • Encrypts file with AES-256-GCM before uploading
  • Updates vault index on remote repository

Examples:

# Upload a single file
./zep upload ./document.pdf documents/report.pdf

# Upload to nested folders (creates folders automatically)
./zep upload ./archive.zip backups/2024/full_backup.zip

# Update an existing file
./zep upload ./updated_report.pdf documents/report.pdf

# Using stateless mode
./zep upload -u myusername ./file.pdf documents/file.pdf

Session Behavior:

  • If you have a persistent session (zephyrus.conf), it updates the local cache
  • If using stateless mode, authentication happens once per command
  • After upload, index is synced to remote repository

File Size: No hard limits in the code; practical limits depend on GitHub's API.


download - Download a File

Decrypts and downloads a file from the vault to your local filesystem. Supports both vault downloads and shared file downloads.

Usage:

./zep download <vault-path> <local-path> [--shared <share-string>]

Aliases: down, d, get

Arguments:

  • vault-path (required): Path to the file in the vault (e.g., documents/report.pdf). Use _ when downloading a shared file.
  • local-path (required): Where to save the file on your computer

Flags:

  • --shared (optional): Download a shared file using the share string. Format: username:storage_id:decryption_key

Features:

  • Finds file by vault path (not storage ID)
  • Automatically decrypts using per-file encryption key
  • Validates file authenticity via GCM authentication
  • Supports downloading shared files from other users
  • Fails safely if decryption fails

Examples:

# Download a file from your vault
./zep download documents/report.pdf ./report.pdf

# Download from nested folders
./zep download backups/2024/full_backup.zip ./backup.zip

# Using stateless mode
./zep download -u myusername documents/report.pdf ./report.pdf

# Download with a different name
./zep download documents/report.pdf ./my_report.pdf

# Download a shared file
./zep download _ ./report.pdf --shared "john:a3f2e1c9:abc123def456..."

Error Handling:

  • Returns error if file not found in vault
  • Returns error if vault path points to a folder
  • Returns error if decryption fails (likely wrong password or invalid share key)
  • Returns error if local file write fails

delete - Delete Files or Folders

Deletes a file or entire folder (with all contents) from the vault.

Usage:

./zep delete <vault-path>

Aliases: del, rm, remove

Arguments:

  • vault-path (required): Path to the file or folder to delete

Features:

  • Supports single file deletion
  • Supports recursive folder deletion (all nested files)
  • Removes files from remote repository
  • Updates vault index
  • Syncs changes to GitHub

Examples:

# Delete a single file
./zep delete documents/report.pdf

# Delete an entire folder and all contents
./zep delete documents/archive

# Using stateless mode
./zep delete -u myusername documents/report.pdf

Behavior:

  • File is removed from remote repository
  • Folder deletion removes all nested files recursively
  • Vault index is updated immediately
  • Changes are committed and pushed to GitHub

Irreversible: Deleted files are not recoverable unless you have git history to roll back.


ls - List Vault Contents

Lists all files and folders in a vault directory with formatted output.

Usage:

./zep ls [folder]

Arguments:

  • folder (optional): Path to list (e.g., documents). Defaults to root if not provided.

Output Format:

NAME            TYPE    STORAGE ID
----            ----    ----------
document.pdf    [FILE]  a3f2e1c9d4b6f8e2
archive/        [DIR]   -

Examples:

# List root of vault
./zep ls

# List a specific folder
./zep ls documents

# List nested folder
./zep ls documents/archive

# Using stateless mode
./zep ls -u myusername documents

Output Details:

  • NAME: File or folder name (folders have "/" suffix)
  • TYPE: [FILE] or [DIR]
  • STORAGE ID: Hex-encoded storage ID for files, "-" for folders

Note: Storage IDs are randomly generated identifiers; they don't reveal original file names.


search - Search the Vault

Searches for files and folders by name or path using case-insensitive substring matching.

Usage:

./zep search <query>

Aliases: s

Arguments:

  • query (required): Search term (case-insensitive, substring matching)

Features:

  • Case-insensitive matching
  • Searches both file names and full paths
  • Displays results in formatted table
  • Searches all folders recursively

Examples:

# Search for files with "report" in the name
./zep search report
# Output:
# VAULT PATH              TYPE    STORAGE ID
# ----------              ----    ----------
# documents/report.pdf    [FILE]  a3f2e1c9d4b6f8e2
# archive/2024_report     [DIR]   -

# Search by file type
./zep search .pdf

# Search by year
./zep search 2024

# Search by path
./zep search documents/invoices

# Using stateless mode
./zep search -u myusername "backup"

Search Matching:

  • Matches if query appears anywhere in the file name or full path
  • "report" matches "report.pdf", "2024_report", "reports/quarterly"
  • ".pdf" matches all PDF files
  • "2024" matches any file or folder with "2024" in the path

Output: If no matches found, displays "No matches found."


share - Generate a Share String for a File

Generates a secure share string that allows others to download a specific file without requiring access to your entire vault.

Usage:

./zep share <vault-path>

Aliases: sh

Arguments:

  • vault-path (required): Path to the file in the vault (e.g., documents/report.pdf)

What It Does:

  1. Locates the file in your vault index
  2. Decrypts the file's encryption key using your vault password
  3. Generates a share string: username:storage_id:decryption_key
  4. Displays the share string and usage instructions

Features:

  • Generates unique per-file share tokens
  • Recipient gets access to only that file, not your entire vault
  • Share token includes the unique encryption key for that file
  • Can be revoked by changing the file (uploading a new version)
  • Works with files from any vault

Examples:

# Share a file from your vault
./zep share documents/report.pdf
# Output:
# Share this string to allow others to download the file:
# john:a3f2e1c9:abc123def456789abc123def456789ab
#
# Recipient can download with:
#   zep download _ output.file --shared "john:a3f2e1c9:abc123def456789abc123def456789ab"

# Using stateless mode
./zep share -u myusername documents/sensitive_file.pdf

Security Implications:

  • Revocation: No way to revoke a share without changing the file
  • Access: Recipient only gets access to that specific file
  • Key Exposure: The encryption key is exposed in the share string; share securely (encrypted email, secure messaging, etc.)
  • No Audit: You cannot see who has downloaded the shared file

Best Practices for Sharing:

  1. Share the string via secure channels (encrypted email, password manager, Signal, etc.)
  2. Never share via unencrypted channels like plain email or messaging apps
  3. For sensitive files, consider sharing a copy instead of the original
  4. If compromised, delete and re-upload the file to invalidate the share

disconnect - Remove Local Session

Clears the local session cache and removes zephyrus.conf.

Usage:

./zep disconnect

Aliases: disc, logout, signout, logoff, exit, dc

What It Does:

  • Removes zephyrus.conf from the current directory
  • Clears in-memory session cache
  • Returns you to unauthenticated state

Examples:

./zep disconnect
# ✔ Logged out.

# All subsequent commands require authentication
./zep ls
# No active session. Enter GitHub Username: ...

When to Use:

  • Before leaving a shared machine
  • To switch to a different account
  • To clear cached credentials

Note: Doesn't affect files in the vault, only removes local cache.


purge - Wipe the Entire Vault

Completely removes all files and history from the remote vault. This is irreversible.

Usage:

./zep purge

What It Does:

  1. Asks for confirmation (type y to confirm)
  2. Creates an empty git repository
  3. Force-pushes to GitHub, erasing all history
  4. Clears the local vault index
  5. Returns to unauthenticated state

Example:

./zep purge
# ⚠️  Confirm PURGE? This wipes all remote data and history. (y/N): y
# ✔ Remote vault has been wiped and local index cleared.

⚠️ WARNING: This operation is permanent and irreversible.

  • All files are deleted
  • All git history is erased
  • GitHub repository cannot recover the data
  • Only use if you're absolutely certain

When to Use:

  • You want to completely reset your vault
  • You're decommissioning the vault
  • You suspect a security compromise and want a clean slate

read - Display File Contents

Read and display file contents directly from the vault without downloading to disk.

Usage:

./zep read <vault-path> [--shared <share-string>]

Aliases: cat, view, display

Arguments:

  • vault-path: Path to file in vault

Flags:

  • --shared <share-string>: Read a shared file

Examples:

# Read a text file
./zep read documents/notes.txt

# Read with pipes
./zep read documents/log.txt | grep ERROR

# Read shared file
./zep read _ --shared "username:ref:password:base64"

Use Cases:

  • Quick file preview without saving to disk
  • Content search and filtering
  • Viewing configuration files
  • Checking log files

Note: Best for text files. Binary files will appear as gibberish.


info - Display Vault or File Information

Get detailed information about your vault or specific files.

Usage:

./zep info [file-path]

Examples:

# Vault statistics (no arguments)
./zep info
# Output: Total files, folders, size, settings, etc.

# File information
./zep info documents/report.pdf
# Output: File size, storage ID, encryption key, path, etc.

Shows:

  • When called without arguments:

    • Total files and folders
    • Total vault size
    • Commit author and message settings
    • File/share hash lengths
  • When called with file path:

    • File name, path, type
    • Storage ID and encrypted key
    • File size
    • Folder contents summary

Use Cases:

  • Audit vault size and contents
  • Verify file metadata before sharing
  • Check storage efficiency
  • Find large files

settings show - Display Vault Settings

Display all current vault configuration settings.

Usage:

./zep settings show

Example Output:

=== Vault Settings ===
Commit Author: Zephyrus <auchrio@proton.me>
Commit Message: Zephyrus: Updated Vault
File Hash Length: 16 chars
Share Hash Length: 6 chars

Shows:

  • Git commit author name and email
  • Default commit message
  • File storage ID length
  • Share reference hash length

settings set - Modify Vault Settings

Update specific vault configuration values.

Usage:

./zep settings set <key> <value>

Arguments:

  • key: Setting to modify (case-insensitive)
    • author_name - Git commit author
    • author_email - Git commit email
    • commit_message - Default commit message
    • file_hash_length - Storage ID length (8-64)
    • share_hash_length - Share ref length (4-32)
  • value: New value for setting

Examples:

# Custom git author
./zep settings set author_name "Engineering Team"
./zep settings set author_email "eng@company.com"

# Longer hash lengths
./zep settings set file_hash_length 32
./zep settings set share_hash_length 8

# Custom commit message
./zep settings set commit_message "Daily Backup"

Effect: All future operations use updated settings in git history.


shared info - View Share Details

Get detailed information about a specific share.

Usage:

./zep shared info <share-id>

Arguments:

  • share-id: Share reference ID

Example:

./zep shared info 72cTWg
# Output: Filename, vault path, creation date, share details

localls - List Local Files

List files from your local filesystem. REPL-only command.

Usage (REPL only):

zep> localls [arguments]

Aliases: lls

Arguments: Pass any ls (Unix/Linux) or dir (Windows) arguments

Behavior:

  • Linux/macOS: Runs ls command
  • Windows: Runs ls if available, falls back to dir

Examples:

zep> lls
zep> lls Documents
zep> lls -la
zep> lls *.pdf

Use Cases:

  • Verify files exist before upload
  • Navigate local directories in REPL
  • No need to exit shell to check files

localdir - Detailed Local Directory Listing

List files with detailed information from your local filesystem. REPL-only command.

Usage (REPL only):

zep> localdir [arguments]

Aliases: ldir

Arguments: Pass any dir (Windows) or ls (Unix/Linux) arguments

Behavior:

  • Windows: Runs dir with detailed output
  • Linux/macOS: Runs ls -la for equivalent detail

Examples:

zep> ldir
zep> ldir Downloads
zep> ldir /A

Use Cases:

  • Check file sizes before upload
  • Verify file modification times
  • Monitor directory state
  • Confirm file availability

Usage Patterns

Pattern 1: Interactive Shell (Recommended)

Best for multiple operations in one session:

./zep
# Username: myusername
# Password: ••••••••••
# ✔ Welcome, myusername. Session Active.

zep> upload ./report.pdf documents/2024/Q1.pdf
zep> upload ./budget.xlsx documents/2024/budget.xlsx
zep> ls documents/2024
zep> search Q1
zep> download documents/2024/Q1.pdf ./Q1_backup.pdf
zep> exit

Pattern 2: Persistent Session

Best for scripting or multiple commands:

./zep connect myusername
# Password: ••••••••••
# ✔ Connected.

./zep upload ./file1.pdf documents/file1.pdf
./zep upload ./file2.pdf documents/file2.pdf
./zep ls documents
./zep disconnect

Pattern 3: One-Off Commands with Stateless Mode

Best for single commands without persistent session:

./zep upload -u myusername ./file.pdf documents/file.pdf
# Password: ••••••••••
# ✔ Upload successful.

./zep download -u myusername documents/file.pdf ./file.pdf
# Password: ••••••••••
# ✔ Download successful.

Pattern 4: Automated Vault Access (CI/CD)

Store credentials securely and run commands programmatically:

# In your automation script
export ZEPHYRUS_USER="myusername"
export ZEPHYRUS_PASS="vaultpassword"  # Handle securely!

./zep upload -u $ZEPHYRUS_USER backup.zip backups/$(date +%Y-%m-%d).zip

Security Considerations

Encryption Architecture

Vault-Level Encryption:

  • Your GitHub SSH key is encrypted with your vault password using AES-256-GCM
  • The vault index is encrypted with your vault password using AES-256-GCM
  • Algorithm: AES-256-GCM (authenticated encryption)
  • Key Derivation: PBKDF2 with 100,000 iterations and SHA-256
  • Nonce: 12-byte random nonce per encryption

Per-File Encryption:

  • Each file has its own unique 32-byte encryption key
  • File keys are encrypted with your vault password and stored in the index
  • File content is encrypted with the per-file key using AES-256-GCM
  • Separate nonce for each file encryption

Sharing:

  • Shared files expose only the per-file key, not your vault password
  • Recipients cannot access other files in your vault
  • Each file can have multiple share links without affecting security of other files

Your files are encrypted before leaving your computer. GitHub never sees unencrypted data.

Authentication

  • SSH Keys: Uses your GitHub SSH key for repository access
  • Vault Password: Encrypts your GitHub SSH key
  • Password Storage: Never stored; must be provided each session

Best Practices

  1. Secure Your SSH Key:

    • Don't share your GitHub SSH key
    • Use SSH key passphrases if your SSH client supports it
    • Store keys on encrypted drives
  2. Protect Your Vault Password:

    • Use a strong, unique password (minimum 12 characters recommended)
    • Don't share it with others
    • Don't store it in plain text
    • Your vault password protects both your SSH key and all file encryption keys
  3. Manage zephyrus.conf:

    • Don't commit zephyrus.conf to git
    • Delete it after sensitive operations
    • It's not encrypted; treat it like a session token
  4. Repository Access:

    • Keep your .zephyrus repository private
    • Only share SSH access with trusted users
    • Consider using deploy keys for automated access
  5. File Sharing Security:

    • Share file links only via secure channels (encrypted email, secure messaging, password managers)
    • Never share via plain email or unencrypted messaging
    • If a share link is compromised, delete and re-upload the file to invalidate it
    • Document who you've shared files with in case of security incidents
  6. Backup Your SSH Key:

    • Store a secure copy of your GitHub SSH key
    • If lost, you'll need to regenerate it
    • Update in Zephyrus vault after key rotation
  7. Revoke Access:

    • To revoke a shared file link, re-upload the file with new content
    • This generates a new per-file key, invalidating previous share links
    • Delete the file to permanently revoke all share links

Troubleshooting

"Auth failed: invalid password"

Cause: Incorrect vault password Solution: Double-check your vault password and try again

"Master key not found"

Cause: Vault not initialized or .config/key missing from repository Solution: Run ./zep setup to initialize the vault

"Repository '.zephyrus' not found"

Cause: .zephyrus repository doesn't exist on GitHub Solution: Create an empty repository named .zephyrus on GitHub

"Failed to clone: repository not found"

Cause: SSH key doesn't have access to the repository Solution:

  • Verify SSH key is added to GitHub account
  • Test with: ssh -T git@github.com
  • Ensure key path in setup is correct

"Path component not found"

Cause: File or folder doesn't exist at that path Solution: Use ls or search to find the correct path

"Is a directory, you can only download individual files"

Cause: Trying to download a folder instead of a file Solution: Use ls to find individual files within the folder

"Decryption failed: check your password"

Cause: Vault password is incorrect or file is corrupted Solution: Verify vault password; if file was uploaded successfully, password should work

SSH Issues on Windows

Problem: SSH key not found on Windows Solution:

  • Use full path to key: C:\Users\YourName\.ssh\id_ed25519
  • Or copy key to a known location and reference it
  • Ensure OpenSSH is installed

Permission Denied Errors

Cause: Insufficient access to GitHub repository Solution:

  • Verify you own the .zephyrus repository
  • Check SSH key permissions: ls -l ~/.ssh/id_ed25519 (should be 600 or 400)
  • On Windows, ensure OpenSSH has correct permissions

File Format and Structure

Vault Structure

Your vault is stored in a GitHub repository with this structure:

.zephyrus/
├── .config/
│   ├── key        (encrypted SSH key)
│   └── index      (encrypted vault index)
├── <hex_id_1>     (encrypted file)
├── <hex_id_2>     (encrypted file)
└── <hex_id_3>     (encrypted file)

Index Format

The index file is encrypted JSON that maps paths to storage IDs:

{
  "documents": {
    "type": "folder",
    "contents": {
      "report.pdf": {
        "type": "file",
        "realName": "a3f2e1c9d4b6f8e2"
      }
    }
  }
}

Encryption Format

Encrypted files follow this format:

[16-byte salt][12-byte nonce][encrypted data + auth tag]

This allows each encryption to use a unique salt and nonce, preventing patterns.

Advanced Usage

Switching GitHub Accounts

To use a different GitHub account:

./zep disconnect
./zep connect different_username
# Password: ••••••••••

This creates a new session for the different account. Note: You need a separate .zephyrus repository for each account.

Migrating Vaults

To move your vault to a new GitHub account you can transfer ownership of the repository or you can migrate manually by:

  1. Create new .zephyrus repository on new account
  2. ./zep setup new_username path/to/key
  3. Download all files from old vault
  4. Upload them to new vault
  5. Delete old .zephyrus repository

Files in the vault are never visible to GitHub or other services.

Getting Help

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

License

Zephyrus CLI is released under the MIT License. See LICENSE file for details.

Disclaimer

Zephyrus CLI is provided as-is. While we've implemented industry-standard encryption, we recommend:

  • Testing with non-critical files first
  • Maintaining separate backups of important data
  • Keeping your vault password secure
  • Regularly updating to the latest version

Data loss or security issues may occur. Use at your own risk.