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
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
-
Backup private keys securely
# Encrypt your private key with another key age -p -o age_key.txt.age ~/.ssh/age_key.txt -
Use strong passphrases (20+ characters recommended)
-
Keep private keys on secure storage (encrypted partition, secure enclave)
-
Rotate keys periodically for long-term secrets
-
Don’t share private keys - only public keys
📋 Organization
-
Use consistent naming conventions
# Format: project_purpose_date.age project_config_2025-01.age backup_full_2025-01-28.tar.gz.age -
Maintain recipients file in version control
git add recipients.txt -
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
-
Generate separate keys for different purposes
-
Use passphrase encryption for temporary secrets
-
Use key-based encryption for files meant to be shared
-
Test decryption before deleting originals
age -d -i ~/.ssh/age_key.txt test.age > /dev/null && echo "OK"
⚠️ Common Mistakes to Avoid
- Losing your private key - back it up securely
- Forgetting your passphrase - it cannot be recovered
- Encrypting with wrong public key - verify before encrypting
- Keeping plaintext after encryption - remove original files
- 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
- Official Repository: https://github.com/FiloSottile/age
- Documentation: https://pkg.go.dev/filippo.io/age
- Download: https://github.com/FiloSottile/age/releases
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:
- FiloSottile/age - Official GitHub Repository
- Official documentation and README (as of October 2025)
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!