Key Storage

How amesh protects your private key. Auto-detected per device, from hardware-backed to encrypted file.

How It Works

When you run amesh init, amesh auto-detects the best available key storage on your device. It tries hardware-backed options first and falls back to an encrypted file when hardware storage is unavailable.

You can also choose a backend explicitly:

# Auto-detect (default)
amesh init --name "my-server"

# Force encrypted file (useful for cloud VMs)
amesh init --name "my-server" --backend encrypted-file

Storage Tiers

amesh tries these in order. The first available backend wins.

Tier 1 macOS Secure Enclave

Hardware-backed. The private key is generated inside the Secure Enclave chip and cannot be extracted. Requires a code-signed binary.

Platform: macOS (signed binary) | Key extractable: No
Tier 2 macOS Keychain

OS-level software keychain. Used when the binary is not code-signed (e.g., development builds). Key is protected by macOS access controls.

Platform: macOS (unsigned binary) | Key extractable: By OS owner
Tier 3 Linux TPM 2.0

Hardware-backed via the Trusted Platform Module. Uses tpm2-tools to generate and use keys inside the TPM chip.

Platform: Linux (with TPM 2.0 hardware) | Key extractable: No
Fallback Encrypted File

Software-based fallback for environments without hardware key storage (cloud VMs, containers, CI). The private key is encrypted with AES-256-GCM, derived from an Argon2id-stretched passphrase.

Platform: Any | Key extractable: With passphrase

Choosing a Backend

EnvironmentBackendNotes
macOS laptop/desktopAuto (Keychain/Enclave)Secure Enclave if code-signed
Linux server with TPMAuto (TPM 2.0)Requires tpm2-tools installed
Cloud VM (EC2, GCP, DO)Encrypted fileMost cloud VMs lack TPM access
Docker / containerEncrypted fileMount ~/.amesh as a volume
Local developmentEncrypted fileUse --backend encrypted-file

Encrypted File Details

The encrypted-file backend stores the private key under ~/.amesh/keys/, encrypted with AES-256-GCM. The encryption key is derived from a passphrase using Argon2id.

Passphrase source (in priority order)
(1) AUTH_MESH_PASSPHRASE env var — never touches disk, preferred for production; (2) a dedicated file at ~/.amesh/.passphrase (mode 0400), or the path in AMESH_PASSPHRASE_FILE; (3) legacy identity.json field — auto-migrated to the dedicated file on next read with a one-time warning log.
Auto-generated passphrase
If you don't provide one, amesh init generates a 256-bit random passphrase and writes it to the dedicated file with mode 0400 (read-only owner). Move the file to a secrets manager, tmpfs, or separate mount for real defense-in-depth against filesystem leaks.
File permissions
Keys and identity files are created with mode 0600, the passphrase file with mode 0400, directories with 0700. Only the owner can read.

Software-only protection. The encrypted-file backend protects against targeted leaks of the key file alone, but NOT against any attacker with general filesystem read access on the device — they can read the passphrase file too. For true hardware binding use Secure Enclave (macOS) or TPM 2.0 (Linux). Set AUTH_MESH_PASSPHRASE at runtime (or move the passphrase file to a tmpfs / secrets manager) to keep the secret off durable disk entirely.