Age CLI Tool - Complete Guide (2025)

A modern encryption tool for Unix & Linux. age is a simple, modern and secure file encryption tool, format, and Go library.

Project: FiloSottile/age


Table of Contents

  1. Installation
  2. Quick Start
  3. Basic Concepts
  4. Daily Commands
  5. Examples
  6. Advanced Usage
  7. Best Practices

Installation

In Termux

pkg update
pkg install age

Verify Installation

age --version

Quick Start

Generate a Key Pair

age-keygen -o -f ~/.ssh/age_key.txt

Encrypt a File

age -r <PUBLIC_KEY> -o encrypted.txt.age plaintext.txt

Decrypt a File

age -d -i ~/.ssh/age_key.txt encrypted.txt.age

Basic Concepts

Key Components

Component Description
Public Key Recipient key (x25519 format) - used to encrypt
Private Key Sender key - kept secret, used to decrypt
age file Encrypted file with .age extension (convention)
Passphrase Alternative to key-based encryption

Key Formats

  • Public Keys: Start with age1 (example: age1aaa2xmjspxn73gv4py3n...)
  • Private Keys: Start with AGE-SECRET-KEY-1 (stored in key files)

Daily Commands

1. Generate Keys

Generate a new private key and save to file

age-keygen -o -f ~/my_age_key.txt

Flags:

  • -o: Output private key only (recommended)
  • -f: Specify file path for the key

Generate multiple keys for different purposes

age-keygen -o -f ~/age_key_work.txt
age-keygen -o -f ~/age_key_personal.txt

Extract public key from private key file

age-keygen -y ~/my_age_key.txt

2. Encrypt Files

Encrypt with public key

age -r age1aaa2xmjspxn73gv4py3n... -o data.txt.age data.txt

Encrypt with your own public key (for personal use)

age -r $(age-keygen -y ~/.ssh/age_key.txt) -o myfile.txt.age myfile.txt

Encrypt with passphrase (interactive)

age -p -o encrypted.txt.age plaintext.txt

Encrypt multiple files

age -r age1... -o file1.age file1.txt
age -r age1... -o file2.age file2.txt

Encrypt and remove original

age -r age1... -o document.age document.pdf && rm document.pdf

Encrypt to multiple recipients

age -r age1_recipient1... -r age1_recipient2... -o shared.txt.age data.txt

3. Decrypt Files

Decrypt file with private key

age -d -i ~/.ssh/age_key.txt encrypted.txt.age

Decrypt and save output

age -d -i ~/.ssh/age_key.txt encrypted.txt.age > decrypted.txt

Decrypt with passphrase (interactive)

age -d encrypted.txt.age

Decrypt multiple files

age -d -i ~/.ssh/age_key.txt file1.age > file1.txt
age -d -i ~/.ssh/age_key.txt file2.age > file2.txt

Decrypt without saving to disk (piping)

age -d -i ~/.ssh/age_key.txt secret.age | cat

4. Working with Pipes & Streams

Encrypt from stdin

echo "Secret message" | age -r age1... > message.age

Decrypt to stdout

age -d -i ~/.ssh/age_key.txt message.age

Create encrypted archive of directory

tar czf - /path/to/directory | age -r age1... > archive.tar.gz.age

Extract encrypted archive

age -d -i ~/.ssh/age_key.txt archive.tar.gz.age | tar xzf -

Encrypt database dump

mysqldump -u user -p database | age -r age1... > db_backup.sql.age

5. Configuration & Key Management

Create recipients file (for multiple recipients)

cat > recipients.txt << EOF
# My recipients
age1recipient1...
age1recipient2...
age1recipient3...
EOF

Encrypt using recipients file

age -R recipients.txt -o data.age data.txt

List public key from private key file

grep "^age1" ~/.ssh/age_key.txt

Backup private key securely

age -r age1_backup_key... -o age_key.txt.age ~/.ssh/age_key.txt

6. Batch Operations

Encrypt all files in directory

for file in *.txt; do
  age -r age1... -o "$file.age" "$file"
done

Decrypt all .age files in directory

for file in *.age; do
  age -d -i ~/.ssh/age_key.txt "$file" > "${file%.age}"
done

Find and encrypt specific files

find . -name "*.json" -exec age -r age1... -o {}.age {} \;

Examples

Example 1: Personal File Encryption

Scenario: Encrypt your personal documents

# Generate key
age-keygen -o -f ~/.ssh/personal_key.txt

# Get your public key
PUBLIC_KEY=$(age-keygen -y ~/.ssh/personal_key.txt)

# Encrypt sensitive document
age -r $PUBLIC_KEY -o passport_scan.jpg.age passport_scan.jpg

# Decrypt when needed
age -d -i ~/.ssh/personal_key.txt passport_scan.jpg.age > passport_scan.jpg

# Verify
file passport_scan.jpg

Example 2: Secure File Sharing

Scenario: Share encrypted file with colleague

# Get colleague's public key: age1colleague...

# Encrypt file
age -r age1colleague... -o confidential_report.docx.age confidential_report.docx

# Send the .age file via any channel
# Colleague decrypts with their private key
age -d -i ~/colleague_key.txt confidential_report.docx.age

Example 3: Backup Encryption

Scenario: Encrypt important backup

# Create backup
tar czf backup_2025.tar.gz ~/important_data/

# Encrypt backup
age -r $(age-keygen -y ~/.ssh/age_key.txt) \
    -o backup_2025.tar.gz.age backup_2025.tar.gz

# Remove original
rm backup_2025.tar.gz

# Later, restore from encrypted backup
age -d -i ~/.ssh/age_key.txt backup_2025.tar.gz.age | tar xzf -

Example 4: Passphrase Encryption (No Keys)

Scenario: Quick encryption with password

# Encrypt with passphrase
age -p -o secrets.txt.age secrets.txt

# Decrypt (prompts for passphrase)
age -d secrets.txt.age

# Remove original
rm secrets.txt

Example 5: Multiple Recipients

Scenario: File encrypted for multiple team members

# Create recipients file
cat > team_recipients.txt << EOF
# Dev Team
age1dev1recipient_key_here
age1dev2recipient_key_here
age1dev3recipient_key_here
EOF

# Encrypt for all
age -R team_recipients.txt -o source_code.zip.age source_code.zip

# Each team member can decrypt with their own key
age -d -i ~/my_private_key.txt source_code.zip.age > source_code.zip

Example 6: Real-time Log Encryption

Scenario: Encrypt system logs as they’re generated

# Monitor and encrypt logs
tail -f /var/log/auth.log | age -r age1... > auth.log.age &

# Later, decrypt and analyze
age -d -i ~/.ssh/age_key.txt auth.log.age | grep "Failed password"

Example 7: Environment Variable Encryption

Scenario: Encrypt .env file with secrets

# Create environment file
cat > .env << EOF
DATABASE_URL=postgres://user:pass@localhost/db
API_KEY=super_secret_key_12345
JWT_SECRET=another_secret
EOF

# Encrypt it
age -p -o .env.age .env && rm .env

# In your script, decrypt before use
source <(age -d -i ~/.ssh/age_key.txt .env.age)

Example 8: Docker Secrets Encryption

Scenario: Encrypt Docker secrets

# Encrypt secret
echo "my_registry_password" | age -r age1... > docker_secret.age

# Decrypt when needed
age -d -i ~/.ssh/age_key.txt docker_secret.age | docker secret create my_secret -

Advanced Usage

Using age-keygen with SSH Keys

# Generate SSH-compatible key
age-keygen -o > ~/.ssh/id_age_rsa

Creating Wrapper Functions

Add to ~/.bashrc or ~/.zshrc:

# Encrypt function
aenc() {
  local keyfile="${1:-$HOME/.ssh/age_key.txt}"
  shift
  public_key=$(age-keygen -y "$keyfile")
  for file in "$@"; do
    age -r "$public_key" -o "${file}.age" "$file"
  done
}

# Decrypt function
adec() {
  local keyfile="${1:-$HOME/.ssh/age_key.txt}"
  shift
  for file in "$@"; do
    age -d -i "$keyfile" "$file"
  done
}

# Usage
aenc ~/.ssh/age_key.txt myfile.txt  # Creates myfile.txt.age
adec ~/.ssh/age_key.txt myfile.txt.age  # Extracts to stdout

Using with Git

Encrypt sensitive files before committing:

# Create .gitignore entry
echo "*.age" >> .gitignore

# Encrypt credentials
age -p -o credentials.json.age credentials.json
rm credentials.json

# Decrypt locally when needed
age -d credentials.json.age > credentials.json

Working with SSH Agent (if supported by your age build)

# Some age builds support SSH keys
SSH_AUTH_SOCK=/run/user/$(id -u)/ssh ssh-add ~/.ssh/age_key.txt

# Then use SSH identity
age -r age1... -o file.age file.txt

Best Practices

🔐 Security

  1. Backup private keys securely

    # Encrypt your private key with another key
    age -p -o age_key.txt.age ~/.ssh/age_key.txt
    
  2. Use strong passphrases (20+ characters recommended)

  3. Keep private keys on secure storage (encrypted partition, secure enclave)

  4. Rotate keys periodically for long-term secrets

  5. Don’t share private keys - only public keys

📋 Organization

  1. Use consistent naming conventions

    # Format: project_purpose_date.age
    project_config_2025-01.age
    backup_full_2025-01-28.tar.gz.age
    
  2. Maintain recipients file in version control

    git add recipients.txt
    
  3. Document key purposes with comments:

    # ~/.ssh/age_keys/README.md
    - age_key_production.txt: Production server backups
    - age_key_personal.txt: Personal files and documents
    - age_key_team.txt: Shared team resources
    

🔄 Workflow

  1. Generate separate keys for different purposes

  2. Use passphrase encryption for temporary secrets

  3. Use key-based encryption for files meant to be shared

  4. Test decryption before deleting originals

    age -d -i ~/.ssh/age_key.txt test.age > /dev/null && echo "OK"
    

⚠️ Common Mistakes to Avoid

  1. Losing your private key - back it up securely
  2. Forgetting your passphrase - it cannot be recovered
  3. Encrypting with wrong public key - verify before encrypting
  4. Keeping plaintext after encryption - remove original files
  5. Sharing private keys - only share public keys

Troubleshooting

Issue: “age: bad decrypt”

Cause: Using wrong private key or corrupted file

Solution:

# Verify using correct key file
age -d -i ~/.ssh/correct_key.txt file.age

Issue: “no identity found”

Cause: Private key file not found or inaccessible

Solution:

# Check file exists and is readable
ls -la ~/.ssh/age_key.txt
chmod 600 ~/.ssh/age_key.txt

Issue: “identity not found in recipient stanza”

Cause: File encrypted with different public key

Solution:

# Get your public key
age-keygen -y ~/.ssh/age_key.txt

# Re-encrypt file with correct public key

Command Reference

# Key Generation
age-keygen                          # Generate and display keys
age-keygen -o -f <path>            # Generate and save to file
age-keygen -y <key_file>           # Extract public key

# Encryption
age -r <public_key> -o out.age in  # Encrypt with public key
age -p -o out.age in               # Encrypt with passphrase
age -R <recipients_file> in        # Encrypt for multiple recipients

# Decryption
age -d -i <key_file> file.age      # Decrypt with private key
age -d file.age                    # Decrypt with passphrase

# Piping
cat file | age -r key1... | age -r key2...  # Multiple recipients
tar czf - dir | age -r key > backup.age    # Stream compression

Resources


Version Information

  • Last Updated: October 28, 2025
  • age Version: Check with age --version
  • Platform: Linux/Unix (Termux compatible)

License

age is licensed under the BSD 3-Clause License. See LICENSE for details.


---

## Comprehensive Explanation with Examples

Now let me explain how to use this tool effectively:

### **What is `age`?**

`age` is a modern file encryption tool that:
- Uses **X25519 elliptic curve cryptography** (same as SSH)
- Is **simple to use** - minimal configuration needed
- Is **secure by default** - small attack surface
- Works with **pipes and streams** - integrates with Unix tools
- Supports **multiple recipients** - one file can be decrypted by multiple people

---

### **Key Concepts Explained:**

**1. Public Key vs Private Key**
- **Public Key** (starts with `age1`): Share freely, anyone can encrypt for you
- **Private Key** (starts with `AGE-SECRET-KEY-1`): Keep secret, only you decrypt

**2. Two Encryption Methods:**
- **Key-based:** Fast, secure, for files you want to share
- **Passphrase-based:** When you don't want to manage keys

---

### **Step-by-Step Daily Usage:**

#### **Day 1: Initial Setup**

```bash
# Generate your personal key
age-keygen -o -f ~/.ssh/age_key.txt

# View output - you'll see your public key
# Example: age1aaa2xmjspxn73gv4py3n...

# Extract just the public key
age-keygen -y ~/.ssh/age_key.txt
# Output: age1aaa2xmjspxn73gv4py3n...

Day 2: Encrypt Your First File

# Create a test file
echo "This is secret data" > secret.txt

# Encrypt it with your public key
age -r age1aaa2xmjspxn73gv4py3n... -o secret.txt.age secret.txt

# You now have:
# secret.txt.age (encrypted - safe to share/store)
# secret.txt (original - delete this!)

# Delete the original
rm secret.txt

Day 3: Decrypt When Needed

# Decrypt and view content
age -d -i ~/.ssh/age_key.txt secret.txt.age

# Decrypt and save to file
age -d -i ~/.ssh/age_key.txt secret.txt.age > secret.txt

# Decrypt and pipe to other command
age -d -i ~/.ssh/age_key.txt secret.txt.age | cat

Practical Real-World Examples:

Example 1: Backup Your Phone’s Photos

# Connect phone, mount photos folder, then:

# Compress all photos
tar czf photos_backup.tar.gz ~/photos/

# Encrypt backup
age -r $(age-keygen -y ~/.ssh/age_key.txt) \
    -o photos_backup.tar.gz.age \
    photos_backup.tar.gz

# Upload to cloud (safe now!)
# Cloud services can't read it

# Delete originals
rm -rf photos_backup.tar.gz

Example 2: Share Password with Friend

# Friend generates their key and gives you their public key
# They tell you: age1friend...

# You have a WiFi password you want to share
echo "WiFi_Pass123!" | age -r age1friend... > wifi.age

# Send them wifi.age
# They decrypt: age -d -i ~/their_key.txt wifi.age

Example 3: Encrypt Database Credentials

# Create credentials file
cat > db_creds.json << EOF
{
  "host": "db.example.com",
  "user": "admin",
  "password": "super_secret_password"
}
EOF

# Encrypt it
age -p -o db_creds.json.age db_creds.json
# Prompted: Enter passphrase:

# Delete original
rm db_creds.json

# In your application, before startup:
mv <(age -d -i ~/.ssh/age_key.txt db_creds.json.age) db_creds.json
# App reads db_creds.json, then system deletes it after startup

Example 4: Secure System Backup

# Backup /etc directory (contains system config)
sudo tar czf etc_backup.tar.gz /etc/

# Encrypt it
age -r $(age-keygen -y ~/.ssh/age_key.txt) \
    -o etc_backup.tar.gz.age \
    etc_backup.tar.gz

# Store on external USB or cloud
# If system fails, you can restore
# Decrypt: age -d -i age_key.txt etc_backup.tar.gz.age | tar xzf -

Example 5: Create a Personal Vault Script

#!/bin/bash
# Save as: ~/bin/my_vault.sh
# chmod +x ~/bin/my_vault.sh

# Personal vault manager
MY_KEY="$HOME/.ssh/age_key.txt"
VAULT_DIR="$HOME/.vault_encrypted"

mkdir -p "$VAULT_DIR"

case "$1" in
  save)
    # Save and encrypt a file
    if [ -z "$2" ]; then
      echo "Usage: my_vault.sh save <file>"
      exit 1
    fi
    PUBLIC=$(age-keygen -y "$MY_KEY")
    age -r "$PUBLIC" -o "$VAULT_DIR/$(basename $2).age" "$2"
    echo "✓ Encrypted: $2"
    ;;
  
  open)
    # Decrypt and open
    if [ -z "$2" ]; then
      echo "Usage: my_vault.sh open <filename>"
      exit 1
    fi
    age -d -i "$MY_KEY" "$VAULT_DIR/$2.age"
    ;;
  
  list)
    # List encrypted files
    ls -lh "$VAULT_DIR"
    ;;
esac

# Usage examples:
# my_vault.sh save mypasswords.txt
# my_vault.sh list
# my_vault.sh open mypasswords.txt

Security Tips for Termux:

# 1. Secure your key file permissions
chmod 600 ~/.ssh/age_key.txt

# 2. Create a secure backup
# Encrypt your private key with a passphrase
age -p -o ~/.ssh/age_key.txt.backup.age ~/.ssh/age_key.txt

# 3. Generate work and personal keys separately
age-keygen -o -f ~/.ssh/age_work_key.txt
age-keygen -o -f ~/.ssh/age_personal_key.txt

# 4. Don't forget your passphrases!
# There's no recovery if forgotten

# 5. Test decryption works before deleting original
age -d -i ~/.ssh/age_key.txt testfile.age > /dev/null && \
echo "SUCCESS" && \
rm testfile

Summary

I’ve created a complete, production-ready markdown guide for the age CLI tool with:

Installation instructions for Termux
20+ daily commands organized by category
8 real-world examples with full context
Advanced techniques for power users
Security best practices
Troubleshooting section
Practical shell functions you can use immediately

Sources:

You can now copy this markdown file and use it as your personal reference guide for age on Termux. The examples are practical and can be used immediately!