🔐 Lightweight CLI utility designed to synchronize SSH public keys from remote URLs into local authorized_keys files
  • Go 98.1%
  • Dockerfile 1.9%
Find a file
2025-12-03 02:37:55 +00:00
.devcontainer Add LLMs section to mkdocs.yml, install mkdocs-llmstxt in Dockerfile, and update GitHub Actions to include mkdocs-llmstxt. Introduce llms-link.js to open llms.txt links in a new tab 2025-12-03 02:37:55 +00:00
.github/workflows Add LLMs section to mkdocs.yml, install mkdocs-llmstxt in Dockerfile, and update GitHub Actions to include mkdocs-llmstxt. Introduce llms-link.js to open llms.txt links in a new tab 2025-12-03 02:37:55 +00:00
cmd Implement platform check in main.go to restrict AuthKeySync usage to Linux and macOS, providing error messages for unsupported platforms. 2025-12-01 19:14:21 +00:00
docs Add LLMs section to mkdocs.yml, install mkdocs-llmstxt in Dockerfile, and update GitHub Actions to include mkdocs-llmstxt. Introduce llms-link.js to open llms.txt links in a new tab 2025-12-03 02:37:55 +00:00
e2e Add end-to-end tests for AuthKeySync, including multiple user scenarios, backup handling, and error response validation. Update Taskfile.yml to include e2e tests in CI pipeline. 2025-12-02 04:13:28 +00:00
examples Add example configuration file for AuthKeySync. Included sample user entries and policy settings for backup and key synchronization. This serves as a reference for users to set up their configurations effectively. 2025-11-30 06:49:22 +00:00
internal Remove truncateKey function and its associated test from sync package to streamline codebase and improve maintainability. 2025-12-01 19:39:32 +00:00
.gitignore Add 'site/' directory to .gitignore to exclude site-related files from version control. 2025-11-30 07:54:06 +00:00
.golangci.yaml Add GolangCI configuration file for linting setup. Enabled specific linters including errcheck, govet, ineffassign, staticcheck, unused, bodyclose, and modernize to improve code quality and maintainability. 2025-11-30 06:59:19 +00:00
AGENTS.md Update AGENTS.md to reference the correct specification file path and add new docs/spec.md for detailed technical specifications of AuthKeySync. 2025-12-01 07:22:49 +00:00
dprint.json Add dprint configuration file for code formatting with specified plugins and exclusions 2025-11-30 04:13:50 +00:00
go.mod Update go.mod and go.sum to include go-nanoid v2.1.0 dependency for secure ID generation. 2025-11-30 07:07:07 +00:00
go.sum Update go.mod and go.sum to include go-nanoid v2.1.0 dependency for secure ID generation. 2025-11-30 07:07:07 +00:00
LICENSE Initial commit 2025-11-29 21:25:40 -06:00
mkdocs.yml Add LLMs section to mkdocs.yml, install mkdocs-llmstxt in Dockerfile, and update GitHub Actions to include mkdocs-llmstxt. Introduce llms-link.js to open llms.txt links in a new tab 2025-12-03 02:37:55 +00:00
README.md Enhance logging options in AuthKeySync by adding --quiet and --silent flags for reduced output in cron jobs, and update documentation to reflect new log levels and usage examples. 2025-12-01 19:07:58 +00:00
Taskfile.yml Add end-to-end tests for AuthKeySync, including multiple user scenarios, backup handling, and error response validation. Update Taskfile.yml to include e2e tests in CI pipeline. 2025-12-02 04:13:28 +00:00

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.