Skip to content

πŸ” Lightweight CLI utility designed to synchronize SSH public keys from remote URLs into local authorized_keys files

License

Notifications You must be signed in to change notification settings

eduardolat/authkeysync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

67 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AuthKeySync Logo

AuthKeySync

Automatically synchronize SSH public keys from remote URLs to your servers

CI Status Go Report Card Release Version License

πŸ“– Full Documentation

The Problem

Managing SSH access across multiple servers is painful:

  • Team members join or leave, and you need to update authorized_keys on every server
  • Developers rotate their SSH keys, and now you have 20 servers to update
  • You're using Infrastructure as Code, but SSH key management is still manual
  • Homemade bash scripts for key management are often poorly written, insecure, or have subtle bugs that can lock you out of your servers
  • You want to use GitHub/GitLab keys, but copying them everywhere is tedious

The Solution

AuthKeySync is a lightweight CLI that fetches SSH public keys from URLs (GitHub, GitLab, your own API) and syncs them to your servers. It's safe, reliable, and designed for automation.

# /etc/authkeysync/config.yaml
users:
  - username: "deploy"
    sources:
      - url: "https://github.com/your-username.keys"
      - url: "https://github.com/another-username.keys"

Run authkeysync (manually or via cron), and your authorized_keys is updated. That's it.

Key Features

  • Single binary: No dependencies, just download and run
  • Safe by default: Preserves existing local keys, creates backups, uses atomic writes
  • Fail-safe: If any source fails, the update is aborted to prevent lockouts
  • Flexible sources: GitHub, GitLab, or any URL returning plain text SSH keys
  • API support: POST requests with custom headers for authenticated APIs
  • IaC-ready: Stateless, idempotent, perfect for Ansible/Terraform/cloud-init
  • Cross-platform: Works on Linux and macOS (AMD64 and ARM64)

Quick Start

1. Download

Get the latest binary from the releases page:

# Linux AMD64
curl -Lo authkeysync https://github.com/eduardolat/authkeysync/releases/latest/download/authkeysync-linux-amd64
chmod +x authkeysync
sudo mv authkeysync /usr/local/bin/

2. Configure

Create a config file at /etc/authkeysync/config.yaml:

policy:
  backup_enabled: true # Create backups before changes (default: true)
  backup_retention_count: 10 # Number of backups to keep (default: 10)
  preserve_local_keys: true # Keep keys not in remote sources (default: true)

users:
  - username: "root"
    sources:
      - url: "https://github.com/your-username.keys"

3. Run

# Test first with dry-run
sudo authkeysync --dry-run

# Apply changes
sudo authkeysync

4. Automate

Set up a cron job or systemd timer to run periodically:

# Every 5 minutes (use --quiet to reduce log noise in cron)
echo "*/5 * * * * root /usr/local/bin/authkeysync --quiet" | sudo tee /etc/cron.d/authkeysync

Configuration Options

Policy (all optional)

Option Type Default Description
backup_enabled bool true Create backups before modifying authorized_keys
backup_retention_count int 10 Number of backup files to keep per user
preserve_local_keys bool true Keep existing keys that are not in remote sources

Users (required)

Option Type Required Description
username string Yes System username (e.g., root, deploy)
sources list Yes List of key sources

Sources

Option Type Default Description
url string (required) URL that returns plain text SSH keys
method string GET HTTP method: GET or POST
headers map {} Custom HTTP headers (e.g., for authentication)
body string "" Request body for POST requests
timeout_seconds int 10 Request timeout in seconds

Example with all options

policy:
  backup_enabled: true
  backup_retention_count: 10
  preserve_local_keys: true

users:
  - username: "deploy"
    sources:
      # Simple GitHub keys
      - url: "https://github.com/your-username.keys"

      # Private API with authentication
      - url: "https://keys.yourcompany.com/api/keys"
        method: "POST"
        headers:
          Authorization: "Bearer your-secret-token"
          Content-Type: "application/json"
        body: '{"environment": "production"}'
        timeout_seconds: 5

CLI Options

Option Description
--config <path> Path to config file (default: /etc/authkeysync/config.yaml)
--dry-run Simulate sync without modifying any files
--debug Enable debug logging (most verbose)
--quiet Show only warnings and errors (recommended for cron)
--silent Show only errors (most quiet)
--version Show version information and exit
--help Show help message

Exit Codes

Code Meaning
0 Success: all users processed or skipped
1 Failure: at least one user failed to sync

How It Works

  1. Fetch: Downloads SSH keys from configured URLs
  2. Parse: Validates and deduplicates keys across all sources
  3. Merge: Optionally preserves keys that only exist locally
  4. Write: Atomically updates authorized_keys with proper permissions
  5. Backup: Creates timestamped backups before any changes

If any source fails to fetch, AuthKeySync aborts the update for that user to prevent lockouts. Your existing access remains intact.

Support the Project

If you find AuthKeySync useful, please consider giving it a star on GitHub and following me on X (Twitter) for updates:

License

MIT License. See LICENSE for details.

About

πŸ” Lightweight CLI utility designed to synchronize SSH public keys from remote URLs into local authorized_keys files

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •